c++模版类静态成员引起的怪异问题(跟DLL导出相关),高分相送啊!

jay0518 2014-04-21 05:17:13
hi 各位论坛大小牛:
我今天遇到一个问题,能力有限,解决不了,望各位相助,再次谢谢啦(并高分相送)!
问题描述:
在一个新建的a.DLL工程中,谢了个模版类,头文件内容如下:
//a.h

#pragma once
template <class T>
class Singleton
{
public:
typedef SingleTon<T> Myself;
static MySelf* GetInstance(){
if(instance_ == NULL){
instance_ = new MySelf();
}
return instance_;
}
private:
static MySelf* instance_;
}
template <class T>
SingleTon<T>* SingleTon<T>::instance_ = NULL;
typedef SingleTon<int> IntSingleTon;

此DLL工程中,还有另外一个源码文件,test.h, test.cpp 内含有一个简单的导出函数作为测试:
代码如下:

//test.h
#ifdef TEST_EXPORTS
#define TEST_API __declspec(dllexport)
#else
#define TEST_API __declspec(dllimport)
#endif
TEST_API void PrintTest();


#include "test.h"
#include <stdio.h>
#include "a.h"
TEST_API void PrintTest()
{
printf("IntSington Addr: %p\r\n", IntSingleTon::GetInstance() );
}

以上都是工程DLL中的源码文件,为了测试我又新建了一个Application Console 工程测试,测试代码如下:

#include <stdio.h>
#include "test.h"
int main()
{
PrintTest();
printf("In Exe IntSingleTon Addr:%p\r\n", IntSingleTon::GetInstance() );
return 0;
}

引入DLL关联,编译,运行后,测试结果出乎我的意料:
PrintTest()打印的地址与后面打印语句 打印出两个不同的对象地址。
奇怪了! 急等帮忙! 谢了!



...全文
180 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
j8daxue 2014-04-22
  • 打赏
  • 举报
回复
如果这个类不是模板类则链接不过,在main.cpp所在工程中找不到这些符号,因为它们都是外部的。 由于是不同的模块,且没指明是导出类, 所以在main编译时认为是内部符号,会把这个模板类实例化一下,这个类所有定义都找得到,所以main.cpp所在工程可以链接过。
jay0518 2014-04-21
  • 打赏
  • 举报
回复
to 林老板: 受教了!我之前还真不知道有这种说法,学艺不精啊,还需努力!
taodm 2014-04-21
  • 打赏
  • 举报
回复
珍惜生命,远离扩展dll,只使用纯C接口的标准dll
carylin 2014-04-21
  • 打赏
  • 举报
回复
神仙你也会犯这个错误。 若要导出DLL中类的静态变量,类必须以_declspec(dllimport)方式声明。这里的Singleton类模板没有导出声明,所以其静态变量instance_无法导出,也就是instance_实例在dll和main所在进程中各有一份。
赵4老师 2014-04-21
  • 打赏
  • 举报
回复
《Windows核心编程》 《深入解析Windows操作系统-Windows Internals》

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧