接上一篇。

上一篇的dll在编译过程中一直有一个警告warning C4251: ‘CLASS_TEST::m_structs’ : class ‘std::vector<_Ty>’ needs to have dll-interface to be used by clients of class ,百

度之才发现是因为DLL中导出了STL中的类,二STL中的类默认是没有导出的,因此报告这个警告。

程序中消除warning有两种方法:

消极一点不去理他,反正不是error;

积极一点,则想办法去掉。去掉又用两种方法:一种使用#pragma warning(disable: xxxx),眼不见,心不烦;另外就是找出解决问题的办法了。在头文件中,定义宏

#ifdef DLL_EXPORT
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif

搜索之,得到解决办法,修改后代码如下:

class DLL_API dllBase
{
public:
dllBase ( void );
~dllBase ( void );
int get();
private:
static int base;
template class DLL_API allocator< string >;
template class DLL_API vector<string, allocator< string > >;
vector<string> m_list;
};

可是这样编译又出问题了,error C2252: an explicit instantiation of a template can only occur at namespace scope。继续搜索之,说是应该吧上面的两句话放到类的外面

再次试之,成功了,代码如下

template class DLL_API allocator< string >;
template class DLL_API vector<string, allocator< string > >;
class DLL_API dllBase
{
public:
dllBase ( void );
~dllBase ( void );
int get();
private:
static int base;
vector<string> m_list;
};

注:因为STL中只有vector可以直接导出,所以该方法成功了,若是将vector换成List,则依然会继续报告C4251错误,暂时还不知道怎么解决。

虽然可以使用了,但是每次都在类前面写入那么一大堆东西,看着就有点烦,于是乎发现了一篇非常强大的日志,在其中发现了一个比较好的办法来解决这个问题,具体就不写了。

但是使用它定义的带参数的宏可以比较方便的修改。

代码如下:

#define DLL_STL_LIST( STL_API, STL_TYPE ) \
template class STL_API std::allocator< STL_TYPE >; \
template class STL_API std::vector<STL_TYPE, std::allocator< STL_TYPE > >; DLL_STL_LIST ( DLL_API, string ); class DLL_API dllBase
{
public:
dllBase ( void );
~dllBase ( void );
int get();
private:
static int base;
vector<string> m_list;
};

参考的另一篇博客:

1:情况一
如果类的定义里面仅含有 编译器内置的类型变量, int, float
等等. 或者成员函数仅使用了这些变量作为参数, 那么很简单.
直接
class __declspec(dllexport)
YourClass

{
}
就行了.

2:情况二
如果类内部使用了别的类, 那么别的类最好也导出, 不然,
首先编译的时候会出现编译警告:
warning C4251: needs to have
dll-interface 
意思是,你使用另外的一些类型/接口, 但是这些类型或接口没有导出.
当你的client使用这些类型/接口的时候, 会出错!
class __declspec(dllexport)
YourClass

{
  
YourAnatherClass m_data; // 这里会 出现 warning 4251. 如果YourAnatherClass
没有导出的话.
}
解决办法就是:
在YourAnatherClass定义的地方加上
class __declspec(dllexport)
YourAnatherClass 
{
}
如上, 当你的YourAnatherClass没有导出的时候,
dll的使用方会出现链接错误

3:情况三
当类的内部使用了STL模板的时候, 也会出现C4251警告,
情况会有所不同
class __declspec(dllexport)
YourClass

{
  
vector m_data; // 这里会 出现 warning 4251. 因为vector类型没有被导出
}
上面的使用模板(无论是stl模板,还是自定义模板)的代码,编译dll时会出现C4251警告,
但是dll的使用方, 却不会出现链接错误!!!
这个因为, dll的使用方那里也有一套模板的定义,
当他们使用那个vector的时候, 虽没有导出,
但是用户自己也有一套STL模板(或者是自定义的模板),用户会利用自己的模板实例化这个dll中没有导出的东西!

所以,
对于因为使用STL(或模板)出现的c4251警告, 关闭之即可
#pragma warning(push)
#pragma
warning(disable:4251)
//your declarations that cause
4251
#pragma
warning(pop)

若想不使用通过关闭警告的方式关闭警告, 那么就这样


1)对于用户自定义的模板
  
template class DLLImportExportMacro SomeTemplate;
  
SomeTemplate y;
2)对于STL的模板
template class DLL_API allocator< string >;

template class DLL_API vector<string, allocator< string > >;

vector<string> m_data;

DLL中导出STL模板类的问题的更多相关文章

  1. 怎样从一个DLL中导出一个C++类

    原文作者:Alex Blekhman    翻译:朱金灿 原文来源: http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx 译 ...

  2. MFC DLL中导出函数模板

    //my.h struct AFX_EXT_CLASS B { }; struct AFX_EXT_CLASS C { }; class AFX_EXT_CLASS A { public: templ ...

  3. [转]从普通DLL中导出C++类 – dllexport和dllimport的使用方法(中英对照、附注解)

      这几天写几个小程序练手,在准备将一个类导出时,发现还真不知道如果不用MFC的扩展DLL,是怎么导出的.但我知道dllexport可以导出函数和变量,而且MFC扩展DLL就算是使用了MFC的功能,但 ...

  4. 转:DLL如何导出C++的类

    由于DLL的出现是针对C语言的,本身对C++的支持不够好.所以如何从DLL中导出C++的类作为DLL的API的一部分就成了问题. 我试了一下 class __declspec(dllexport) F ...

  5. DLL入门浅析(4)——从DLL中导出类

    转载自:http://www.cppblog.com/suiaiguo/archive/2009/07/20/90663.html 前面介绍了怎么从DLL中导出函数和变量,实际上导出类的方法也是大同小 ...

  6. 实现MFC扩展DLL中导出类和对话框

    如果要编写模块化的软件,就要对对动态链接库(DLL)有一定的了解,本人这段时间在修改以前的软件时,决定把重复用的类和对话框做到DLL中,下面就从一个简单的例子讲起,如何实现MFC扩展DLL中导出类和对 ...

  7. DLL中传递STL参数,vector对象作为dll参数传递等问题(转)

    STL跨平台调用会出现很多异常,你可以试试. STL使用模板生成,当我们使用模板的时候,每一个EXE,和DLL都在编译器产生了自己的代码,导致模板所使用的静态成员不同步,所以出现数据传递的各种问题,下 ...

  8. DLL中传递STL参数(如Vector或者list等)会遇到的问题[转载]

    最近的一个项目中遇到了调用别人的sdk接口(dll库)而传给我的是一个vector指针,用完之后还要我来删除的情况.这个过程中首先就是在我的exe中将其vector指针转为相应指针再获取vector中 ...

  9. 在DLL中导出另一静态库中的函数

    开发环境: win7_x64.VS2013 应用场景: 动态库A依赖动态库B,而动态库B又使用了静态库C:有些情况下,我们需要将C从B里面导出,然后提供给A使用. 正文: Step1: 1.新建测试静 ...

随机推荐

  1. [liu yanling]测试用例的设计方法

    一.功能测试      1.对话框测试输入进行测试.包括中文字符.英文字符.数字字符.特殊字符.及几种字符的组合.      2.对界面可操作按钮进行测试.包括[新增(N)][保存(S)][修改(M) ...

  2. modsecurity配置指令学习

    事务(transactions) Console(控制台) 1 Introduction Modsecurity是保护网络应用安全的工作.不,从零开始.我常称modsecurity为WAF(网络应用防 ...

  3. Fatjar成功安装记录

    1.FatJar安装方式 (1)在线安装 具体网址http://kurucz-grafika.de/fatjar (2)离线安装 将fatjar的jar放到plugins文件夹中,重启 2. 安装失败 ...

  4. 解决 MyEclipse 10 中 JSp页面 “return false” 报错问题

    1.MyEclipse ->. Preferences 2.validation ->>找到JavaScript validator for Js files  builder 下面 ...

  5. ceph-deploy 在下面ceph-nodes执行的命令

    1,Running command: env DEBIAN_FRONTEND=noninteractive apt-get -q install --assume-yes ca-certificate ...

  6. [置顶] 斗地主算法的设计与实现--项目介绍&如何定义和构造一张牌

    大学期间,我在别人的基础上,写了一个简易的斗地主程序. 主要实现了面向对象设计,洗牌.发牌.判断牌型.比较牌的大小.游戏规则等算法. 通过这个斗地主小项目的练习,提高了我的面向对象设计能力,加深了对算 ...

  7. bug,不该怕~敢敢test就是了

    转载自:http://bbs.itcast.cn/thread-10103-1-1.html 当程序员的经历让我知道了一些关于软件编程的事情.下面的这些事情可能会让朋友们对软件开发感到惊讶: 一个程序 ...

  8. Cocos2d-x 3.0- 在Visual Studio 2012中执行測试项目

    Cocos2d-x - 怎样在Win32执行cpp-tests 2014年4月30日 星期三 小雨 微凉 稍显疲惫 注:本篇文章来自Cocos2d-x官网,小巫仅仅是粗略翻译眼下最新版本号的,教大家怎 ...

  9. ERROR 1045: Access denied for user: 'root@localhost' (Using password: YES)(转)

    前两天也偶尔出现这个错误,也没在意,因为我重新修改一下mysql的root密码后又可以用了,但昨天却不行,我把root密码修改以后虽然当时能用, 一旦重新进入就都不能用了,可我的密码明明没有错啊?今天 ...

  10. android开发工具类之获得WIFI IP地址或者手机网络IP

    有的时候我们需要获得WIFI的IP地址获得手机网络的IP地址,这是一个工具类,专门解决这个问题,这里需要两个权限: <uses-permission android:name="and ...