如何将导出的标准模板库 (STL) 类和包含数据成员是 STL 对象的类的实例化

文章翻译 文章翻译
文章编号: 168958 - 查看本文应用于的产品
展开全部 | 关闭全部

本文内容

概要

本文讨论了如何执行以下任务:
  • 导出实例化的一个标准模板库 (STL) 类。
  • 导出包含一个 STL 的一个数据成员的类对象。
请注意您可以不导出一个通用的模板。必须进行实例化模板 ; 也就是所有模板参数时必须提供,并且必须完全定义的类型的实例化。 实例"堆栈 <int>;"实例化 STL 堆栈类。在实例化强制类堆栈 <int>来生成的所有的成员。

此外请注意一些 STL 容器 (图、 组、 队列、 列表、 deque) 不能被导出。请参阅更多信息一节进行详细说明。

更多信息

从 Visual c + + 5.0 开始就可以强制模板类的实例化和导出实例化。若要导出模板类实例化,使用以下语法:

要导出的 STL 类

  1. 在 DLL 和.exe 文件,链接使用相同的 DLL 的 C 运行时版本。链接都具有 Msvcrt.lib (发布版本),或者链接都具有 Msvcrtd.lib (调试版本)。
  2. 在该的 DLL 中提供了在模板实例化声明 __declspec 说明符,要从 DLL 导出 STL 类实例化。
  3. 在.exe 文件中提供了在模板实例化声明从 DLL 导入类 extern 和 __declspec 说明符。这将导致警告 C4231"使用了非标准扩展: 外部在模板显式实例化之前"您可以忽略此警告。

导出包含数据成员是 STL 对象的类

  1. 在 DLL 和.exe 文件,链接使用相同的 DLL 的 C 运行时版本。链接都具有 Msvcrt.lib (发布版本),或者链接都具有 Msvcrtd.lib (调试版本)。
  2. 在该的 DLL 中提供了在模板实例化声明 __declspec 说明符,要从 DLL 导出 STL 类实例化。

    注:您不能跳过步骤 2。您必须导出用于创建该数据成员的 STL 类的实例化。
  3. 在该的 DLL 中提供了类的声明中 __declspec 说明符,要从 DLL 导出类。
  4. 在.exe 文件中提供了类的声明中 __declspec 说明符,若要从 DLL 导入类。

    如果您要导出的类具有一个或多个基本类,则必须导出同样是基类。如果您要导出的类中包含的类类型的数据成员必须导出同样的数据成员的类。
注:某些 STL 类使用其他 STL 类。此外必须导出这些其他类。必须导出此类列出了编译器警告,如果您使用较低的比 1; 该警告等级、 /W2、 /W3,或 /W4 编译。警告等级 4 生成大量的 STL 标头的警告消息,因此建议不要当前使用的原因。

某些 STL 类包含嵌套的类。这些类不可以被导出。例如,deque 包含嵌套的类 deque::iterator。如果您导出 deque,您将得到一条警告,您必须导出 deque::iterator。如果您导出 deque::iterator,您将获得一条警告,您必须导出 deque。一旦模板类被实例化,它可以不是 re-instantiated 并导出一个设计限制所致。只有当前可以导出 STL 容器是矢量。其他容器 (也就是映射、 组、 队列、 列表、 deque) 所有包含嵌套的类,并且不能被导出。

当您将使用用户定义类型 (UDT) 参数化 STL 容器的导出时,您必须定义运算符 < 和 = = 的 UDT。<myclass>例如对于如果导出矢量 < MyClass >,则必须定义 MyClass::operator < 和 MyClass 运算符 = =。这是因为 STL 容器的所有类都都需要存在的运算符的成员比较运算符 < 和 = = 的包含类型。通常情况下,这些是不被实例化,因为它们未使用。 当实例化模板类的实例时,会生成所有的成员函数。由于 STL 容器类具有使用该运算符的成员函数 < = = 和该包含类型必须实现它们。如果比较的 UDT 对象没有意义,您可以定义所比较的运算符只返回"true。

在编译 (该符号隐式定义用/MD 或 /MDd 链接与 DLL 版本的 C 运行时编译时),下面的 STL 类和各种全局运算符和函数在这些类上操作的过程中定义了符号 _DLL,已导出由 C 运行时 DLL 中。因此,您不能从 DLL 导出它们。这应该不会导致该可执行程序,只要它还使用 C 运行时 DLL 版本中导入您的类的一个问题:
Header      STL template class
------------------------------
<IOSFWD>    basic_ios
<IOSFWD>    <IOSFWD>
<IOSFWD>    basic_istream
<IOSFWD>    basic_string (also typedef'd as string and wstring)
<IOSFWD>    complex
<LOCALE>    messages
<XLOCALE>   codecvt
<XLOCALE>   ctype
<XLOCMON>   moneypunct
<XLOCMON>   money_get
<XLOCMON>   money_put
<XLOCNUM>   numpunct
<XLOCTIME>  time_get
<XLOCTIME>  time_put
<XSTRING>   basic_string (also typedef'd as string and wstring)
				
对于使用哪个模板参数与声明的全局函数和运算符,了的特定详细信息,请参阅相关的头文件。

示例代码

   // -------------------------------------------
   // MYHEADER.H
   //disable warnings on 255 char debug symbols
    #pragma warning (disable : 4786)
   //disable warnings on extern before template instantiation
    #pragma warning (disable : 4231)

    #include <vector>

    // Provide the storage class specifier (extern for an .exe file, null
    // for DLL) and the __declspec specifier (dllimport for .an .exe file,
    // dllexport for DLL).
    // You must define EXP_STL when compiling the DLL.
    // You can now use this header file in both the .exe file and DLL - a
    // much safer means of using common declarations than two different
    // header files.
    #ifdef EXP_STL
    #    define DECLSPECIFIER __declspec(dllexport)
    #    define EXPIMP_TEMPLATE
    #else
    #    define DECLSPECIFIER __declspec(dllimport)
    #    define EXPIMP_TEMPLATE extern
    #endif

    // Instantiate classes vector<int> and vector<char>
    // This does not create an object. It only forces the generation of all
    // of the members of classes vector<int> and vector<char>. It exports
    // them from the DLL and imports them into the .exe file.
    EXPIMP_TEMPLATE template class DECLSPECIFIER std::vector<int>;
    EXPIMP_TEMPLATE template class DECLSPECIFIER std::vector<char>;

    // Declare/Define a class that contains both a static and non-static
    // data member of an STL object.
    // Note that the two template instantiations above are required for
    // the data members to be accessible. If the instantiations above are
    // omitted, you may experience an access violation.
    // Note that since you are exporting a vector of MyClass, you must
    // provide implementations for the operator < and the operator ==.
    class DECLSPECIFIER MyClass
    {
    public:
        std::vector<int> VectorOfInts;
        static std::vector<char> StaticVectorOfChars;

    public:
        bool operator < (const MyClass > c) const
        {
            return VectorOfInts < c. VectorOfInts;
        }
        bool operator == (const MyClass > c) const
        {
            return VectorOfInts == c. VectorOfInts;
        }
    };

    // Instantiate the class vector<MyClass>
    // This does not create an object. It only forces the generation of
    // all of the members of the class vector<MyClass>. It exports them
    // from the DLL and imports them into the .exe file.
    EXPIMP_TEMPLATE template class DECLSPECIFIER std::vector<MyClass>;

    // -------------------------------------------
    // Compile options needed: /GX /LDd /MDd /D"EXP_STL"
    //                     or: /GX /LD  /MD  /D"EXP_STL"
    // DLL.CPP

    #include "MyHeader.h"
    std::vector<char> MyClass::StaticVectorOfChars;

    // -------------------------------------------
    // Compile options needed: /GX /MDd
    //                     or: /GX /MD
    // EXE.CPP

    #include <iostream>
    #include "MyHeader.h"

    int main ()
    {
        MyClass x;

        for (int i=0; i<5; i++) x.VectorOfInts.push_back(i);
        for (char j=0; j<5; j++) x.StaticVectorOfChars.push_back('a' + j);

        std::vector<int>::iterator vii = x.VectorOfInts.begin();
        while (vii != x.VectorOfInts.end())
        {
            std::cout << *vii;
            std::cout << " displayed from x.VectorOfInts" << std::endl;
            vii++;
        }
        std::vector<char>::iterator vci = x.StaticVectorOfChars.begin();
        while (vci != x.StaticVectorOfChars.end())
        {
            std::cout << *vci;
            std::cout << " displayed from MyClass::StaticVectorOfChars";
            std::cout << std::endl;
            vci++;
        }

        std::vector<MyClass> vy;
        for (i=0; i=5; i++) vy.push_back(MyClass());

        return 1;
    }
				

参考

有关更多的信息搜索下列在 Visual c + + 帮助主题:
显式实例化
__declspec
堆栈
/ MD,ML,/MT/LD (使用运行时库)

属性

文章编号: 168958 - 最后修改: 2005年9月6日 - 修订: 3.0
这篇文章中的信息适用于:
  • Microsoft Visual C++ 5.0 企业版
  • Microsoft Visual C++ 6.0 企业版
  • Microsoft Visual C++ 5.0 专业版
  • Microsoft Visual C++ 6.0 专业版
  • Microsoft Visual C++, 32-bit Learning Edition 6.0
关键字:?
kbmt kbstl kbinfo kbcode kbhowto KB168958 KbMtzh
机器翻译
注意:这篇文章是由无人工介入的微软自动的机器翻译软件翻译完成。微软很高兴能同时提供给您由人工翻译的和由机器翻译的文章, 以使您能使用您的语言访问所有的知识库文章。然而由机器翻译的文章并不总是完美的。它可能存在词汇,语法或文法的问题,就像是一个外国人在说中文时总是可能犯这样的错误。虽然我们经常升级机器翻译软件以提高翻译质量,但是我们不保证机器翻译的正确度,也不对由于内容的误译或者客户对它的错误使用所引起的任何直接的, 或间接的可能的问题负责。
点击这里察看该文章的英文版: 168958
Microsoft和/或其各供应商对于为任何目的而在本服务器上发布的文件及有关图形所含信息的适用性,不作任何声明。 所有该等文件及有关图形均"依样"提供,而不带任何性质的保证。Microsoft和/或其各供应商特此声明,对所有与该等信息有关的保证和条件不负任何责任,该等保证和条件包括关于适销性、符合特定用途、所有权和非侵权的所有默示保证和条件。在任何情况下,在由于使用或运行本服务器上的信息所引起的或与该等使用或运行有关的诉讼中,Microsoft和/或其各供应商就因丧失使用、数据或利润所导致的任何特别的、间接的、衍生性的损害或任何因使用而丧失所导致的之损害、数据或利润不负任何责任。

提供反馈

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com