本文翻译自 https://support.microsoft.com/zh-cn/help/168958/how-to-export-an-instantiation-of-a-standard-template-library-stl-clas

概要

本文讨论如何实现下面任务:

  • 导出标准模板库(STL)类的实例化。
  • 导出包含STL类对象数据成员的类。

注意,您无法导出通用的模板,模板必须实例化才能导出。也就是说,必须提供所有的模板参数,并且在实例化时,模板的参数必须是完全定义的类型。例如stack<int>实例化STL堆栈类,实例化时强制生成类stack<int>的所有成员。

还要注意,一些STL容器(map、set、queue、list、deque)无法导出。

更多信息

从VC++ 5.0开始,可以强制对模板类进行实例化并导出实例化类。导出实例化模板类,可使用以下语法:

导出STL类

  1. .dll.exe文件中,必须链接到相同版本的C运行时库dll。两个都链接msvcrt.lib(Release版本)或都链接到msvcrtd.lib(Debug版本)
  2. dll中,在模板的实例化声明中使用__declspec修饰符,以便从dll中导出STL类的实例化。
  3. exe中,需提供使用extern__declspec修饰的模板实例化声明,以便从dll中导入类。 这会导致警告 C4231 "nonstandard extension used : 'extern' before template explicit instantiation." 。 您可以忽略此警告。

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

  1. .dll.exe文件中,必须链接到相同版本的C运行时库dll。两个都链接msvcrt.lib(Release版本)或都链接到msvcrtd.lib(Debug版本)
  2. dll中,在模板的实例化声明中使用__declspec修饰符,以便从dll中导出STL类的实例化。

    注意:不能跳过上一步,用于创建数据成员的STL类必须导出其实例化。
  3. dll中,在类的声明中使用__declspec修饰符,以便从dll中导出类。
  4. exe中,在类的声明中使用__declspec修饰符,以便从dll中导入类。

    如果要导出的类有一个或多个基类,那么其基类也必须导出。如果要导出的类中还包含某类类型的数据成员,则还必须导出数据成员类型的类。

注意:一些STL类使用到其它的STL类,这些依赖的类也必须导出。如果使用低于1的警告级别(也就是/W2/W3/W4),则必须导出类会出现在编译器警告信息中。/W4级别编译时,会因为STL而生成大量警告信息,目前不推荐使用此级别警告。

一些STL类包含嵌套类,所以无法导出这些类。例如,deque包含一个嵌套类deque::iterator如果导出deque,将产生警告信息。,提示你必须导出deque::iterator;如果你导出deque::iterator则会产生警告信息,提示你必须导出deque。这是受限于STL的设计,一旦模板类被实例化,它不能被重新实例化和导出。目前唯一可以导出的STL容器是vector,其它容器(map、set、queue、list、deque)都包含嵌套类无法导出。

导出使用用户定义类型(UDT)作为STL容器模板参数实例化的类时,必须为自定义类型()UDT)重载<==运算符。例如,如果导出vector<MyClass>,则必须定义MyClass::operator<MyClass::==。这是因为所有的STL容器类都具有成员比较运算操作,需要使用到包含类型的<==运算操作。通常,这些都不被实例化,因为它们没有被使用。当实例化一个模板类时,会生成所有的成员函数,因为STL容器类具有使用到<==的成员函数,所有必须实现它们。如果比较UDT的对象没有意义,也可以在定义operator<opeartor==的时候,简单的返回true

当在编译期间发现_DLL已经定义(当使用/MD/MDd编译与C运行时库的DLL版本链接时,该符号被隐含定义),以下STL类以及对这些类的操作的各种全局运算符和函数,已在C运行时库DLL中导出。因此,无法从DLL中导出它们。z只要导入类也使用相同的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;
}

参考

其它相关信息,请在VC++帮助中搜索以下关键字:Explicit Instantiation(显示实例化)、__declspec、stack、/MD, /ML, /MT, /LD (Use Run-Time Library)。

如何导出标准模板库(STL)类的实例化和包含STL类对象数据成员的类的更多相关文章

  1. C++-标准模板库

    C++较之C语言强大的功能之一是,C++编译器自带了大量的可复用代码库,我们称为标准模板库(standard template library),STL.标准模板库是一套常用的数据结构的集合,包括链表 ...

  2. C++标准模板库Stand Template Library(STL)简介与STL string类

    参考<21天学通C++>第15和16章节,在对宏和模板学习之后,开启对C++实现的标准模板类STL进行简介,同时介绍简单的string类.虽然前面对于vector.deque.list等进 ...

  3. STL标准模板库(简介)

    标准模板库(STL,Standard Template Library)是C++标准库的重要组成部分,包含了诸多在计算机科学领域里所常见的基本数据结构和基本算法,为广大C++程序员提供了一个可扩展的应 ...

  4. STL标准模板库介绍

    1. STL介绍 标准模板库STL是当今每个从事C++编程的人需要掌握的技术,所有很有必要总结下 本文将介绍STL并探讨它的三个主要概念:容器.迭代器.算法. STL的最大特点就是: 数据结构和算法的 ...

  5. 【c++】标准模板库STL入门简介与常见用法

    一.STL简介 1.什么是STL STL(Standard Template Library)标准模板库,主要由容器.迭代器.算法.函数对象.内存分配器和适配器六大部分组成.STL已是标准C++的一部 ...

  6. C++——string类和标准模板库

    一.string类 1.构造函数 string实际上是basic_string<char>的一个typedef,同时省略了与内存管理相关的参数.size_type是一个依赖于实现的整型,是 ...

  7. STL 简介,标准模板库

    这篇文章是关于C++语言的一个新的扩展--标准模板库的(Standard Template Library),也叫STL.  当我第一次打算写一篇关于STL的文章的时候,我不得不承认我当时低估了这个话 ...

  8. 标准模板库(STL)学习探究之vector容器

    标准模板库(STL)学习探究之vector容器  C++ Vectors vector是C++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库.vector之所以被 ...

  9. STL学习一:标准模板库理论基础

    STL(Standard Template Library,标准模板库)是惠普实验室开发的一系列软件的统称.现然主要出现在C++中,但在被引入C++之前该技术就已经存在了很长的一段时间. STL的从广 ...

随机推荐

  1. verilog语法实例学习(9)

    常用的时序电路介绍 寄存器 一个触发器可以存储一位数据,由n个触发器组成的电路可以存储n位数据,我们把这一组触发器叫做寄存器.寄存器中每个触发器共用同一个时钟. 下面是n位寄存器的代码,我们通过一个参 ...

  2. frp错误处理:login to server failed: authorization failed

    frp使用过程中会出现各种错误信息,有些朋友不太清楚,打算记录一些常见的错误返回代码,这里介绍一下frpc客户端[W] [control.go:111] login to server failed: ...

  3. LeetCode 114| Flatten Binary Tree to Linked List(二叉树转化成链表)

    题目 给定一个二叉树,原地将它展开为链表. 例如,给定二叉树 1 / \ 2 5 / \ \ 3 4 6 将其展开为: 1 \ 2 \ 3 \ 4 \ 5 \ 6 解析 通过递归实现:可以用先序遍历, ...

  4. 超酷实用的jQuery焦点图赏析及源码

    焦点图应用在现代网页中使用十分广泛,有注重简单小巧的,也有注重华丽美观的,大部分jQuery焦点图都可以滑动和切换图片,并且在切换图片时产生不同的动画特效.今天我们要分享一些超酷而且实用的jQuery ...

  5. 如何清空IFRAME中的HTML

    window.frames["ifra"].document.write(""); window.frames["ifra"].docume ...

  6. Java 解决 servlet 接收参数中文乱码问题

    方法一: 接收到的参数进行如下操作[不建议]: String tmp = new String(type.getBytes("iso-8859-1"), "utf-8&q ...

  7. Linux下C结构体初始化[总结]

    1.前言 今天在公司看一同事写的代码,代码中用到了struct,初始化一个struct用的是乱序格式,如下代码所示: typedef struct _data_t { int a; int b; }d ...

  8. 造轮子 | 怎样设计一个面向协议的 iOS 网络请求库

    近期开源了一个面向协议设计的网络请求库 MBNetwork,基于 Alamofire 和 ObjectMapper 实现,目的是简化业务层的网络请求操作. 须要干些啥 对于大部分 App 而言,业务层 ...

  9. gzcms技术开发文档

    1.输出统一的json格式ajaxJSON.cs: 2.web.config注册html控件:3.gzcms.contrls开发控件库:4.form序列化提交$(this).serializeJson ...

  10. 微信小程序 - 自定义tabbar(组件)

    配置项(关于使用组件) index.wxml <!-- tabBar:tabBar配置 activeIndex: 激活页面下标 slots: 多插槽配置(需与页面一致) --> <t ...