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()打印的地址与后面打印语句 打印出两个不同的对象地址。
奇怪了! 急等帮忙! 谢了!



...全文
106 点赞 收藏 5
写回复
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》
回复 点赞
发动态
发帖子
C++ 语言
创建于2007-09-28

3.1w+

社区成员

24.8w+

社区内容

C++ 语言相关问题讨论,技术干货分享
社区公告
暂无公告