彻底崩溃的VS2005 DLL之Singleton模板
时间:2011-12-15
来源:互联网
class Derived:public TSingleton<Derived>{}
继承自TSingleton<>模板,当new出Derived时,TSingleton<Derived>构造函数向静态变量Derived* s_pInstanceSingleton写入this值.调用TSingleton<>::GetpInstance()能够返回以前写入的this值
问题出在Dll上,使用的是MFC扩展Dll,使用Console调用.测试代码写在Dll01中,TSingleton写在Dll00中.两个Dll中分别定义了一个用于测试的Derived类,分别是CTest02和CTest05,代码几乎一模一样.
类似于
class AFX_EXT_CLASS CTest2:public TSingleton<CTest2>
{
public:
CTest2(void);
virtual ~CTest2(void){}
void SayHello(void)
{
std::cout<<"Hello Test2"<<m_strNameBase<<m_nSeq<<std::endl;
}
void SayHelloMsg(){
AfxMessageBox(_T("Hello Test2"));
}
};
CTest2::CTest2(void):TSingleton(this,"CTest2"){}
Dll01的用例"CTest05"没有问题,异地Dll00的用例 "CTest02"写入后调用GetpInstance返回是Null.后来用GetpInstance2返回了非Null值.但是对象被创建了2次.从Console输出可以看到.
更加诡异的是如果将CTest02的构造函数写在.h文件(class结构内)中,则没有问题.而写在.cpp中,即使加了inline也没有用
template的静态指针型变量 象蒸发了一样.
翻阅了Addison的C++ Templates: The Complete Guide 好像似乎有个章节是CRTP,不过没有深入展开.
安装的是VS2005sp1英文版,不知道是何原因?
MFC Ext Dll00
C/C++ code
MFC EXT DLL01
C/C++ code
MFC console Exe文件,Depends on Dll00,Dll01
C/C++ code
继承自TSingleton<>模板,当new出Derived时,TSingleton<Derived>构造函数向静态变量Derived* s_pInstanceSingleton写入this值.调用TSingleton<>::GetpInstance()能够返回以前写入的this值
问题出在Dll上,使用的是MFC扩展Dll,使用Console调用.测试代码写在Dll01中,TSingleton写在Dll00中.两个Dll中分别定义了一个用于测试的Derived类,分别是CTest02和CTest05,代码几乎一模一样.
类似于
class AFX_EXT_CLASS CTest2:public TSingleton<CTest2>
{
public:
CTest2(void);
virtual ~CTest2(void){}
void SayHello(void)
{
std::cout<<"Hello Test2"<<m_strNameBase<<m_nSeq<<std::endl;
}
void SayHelloMsg(){
AfxMessageBox(_T("Hello Test2"));
}
};
CTest2::CTest2(void):TSingleton(this,"CTest2"){}
Dll01的用例"CTest05"没有问题,异地Dll00的用例 "CTest02"写入后调用GetpInstance返回是Null.后来用GetpInstance2返回了非Null值.但是对象被创建了2次.从Console输出可以看到.
更加诡异的是如果将CTest02的构造函数写在.h文件(class结构内)中,则没有问题.而写在.cpp中,即使加了inline也没有用
template的静态指针型变量 象蒸发了一样.
翻阅了Addison的C++ Templates: The Complete Guide 好像似乎有个章节是CRTP,不过没有深入展开.
安装的是VS2005sp1英文版,不知道是何原因?
MFC Ext Dll00
C/C++ code
//Singleton.h,基础类,检查是否有违规 class AFX_EXT_CLASS CSingleton { protected: static std::set<std::string> s_setStr; public: CSingleton(const std::string& strName); virtual ~CSingleton(void){} }; //Singleton.cpp,基础类,检查是否有违规 std::set<std::string> CSingleton::s_setStr; CSingleton::CSingleton(const std::string& strName) { if(s_setStr.find(strName)!=s_setStr.end()){ std::cout<<"duplicate!"<<std::endl; } s_setStr.insert(strName); } //TSingleton.h,模板类 template<class Tp> class TSingleton:public CSingleton { protected: static Tp* s_pInstanceSingleton; static std::string s_strSingletonName; std::string m_strNameBase; static int m_nSeq; protected: TSingleton(Tp* pThis,const std::string& strT);/*:CSingleton(strT); { s_strSingletonName=strT; s_pInstanceSingleton=pThis; }*/ virtual ~TSingleton(void) { s_pInstanceSingleton=NULL; std::cout<<"deleted: "<<s_strSingletonName<<std::endl; } public: static Tp* GetpInstance() //with no auto create { if(s_pInstanceSingleton){ std::cout<<"GetpInstance() success: "<<s_strSingletonName<<std::endl; return s_pInstanceSingleton; } std::cout<<"fail to load class's instance: "<<s_strSingletonName<<std::endl; return NULL; } static Tp* GetpInstance2() //with auto create { if(s_pInstanceSingleton){ std::cout<<"GetpInstance2() success: "<<s_strSingletonName<<std::endl; return s_pInstanceSingleton; } s_pInstanceSingleton=new Tp; AfxMessageBox(_T("new instance")); return s_pInstanceSingleton; } }; template<class Tp> Tp* TSingleton<Tp>::s_pInstanceSingleton; template<class Tp> std::string TSingleton<Tp>::s_strSingletonName="unknown"; template<class Tp> int TSingleton<Tp>::m_nSeq=0; template<class Tp> TSingleton<Tp>::TSingleton(Tp* pThis,const std::string& strT):CSingleton(strT),s_pInstanceSingleton(pThis) { this->s_strSingletonName=strT; this->s_pInstanceSingleton=pThis; this->m_strNameBase=strT; this->m_nSeq++; std::cout<<m_strNameBase<<" created: "<<m_nSeq<<std::endl; //s_pInstanceSingleton=dynamic_cast<Tp*>(this); } //测试体02.h class AFX_EXT_CLASS CTest2:public TSingleton<CTest2> { public: CTest2(void); virtual ~CTest2(void){} void SayHello(void) { std::cout<<"Hello Test2"<<m_strNameBase<<m_nSeq<<std::endl; } void SayHelloMsg(){ AfxMessageBox(_T("Hello Test2")); } }; //测试体02.cpp CTest2::CTest2(void):TSingleton(this,"CTest2"){}
MFC EXT DLL01
C/C++ code
//测试体05.h #include "stdafx.h" class AFX_EXT_CLASS CTest5:public TSingleton<CTest5> { public: CTest5(void); virtual ~CTest5(void); void SayHello(void); void SayHelloMsg(); }; //测试体05.cpp CTest5::CTest5(void): TSingleton(this,"CTest5") { } CTest5::~CTest5(void) { } void CTest5::SayHello(void) { std::cout<<"Hello Test5"<<std::endl; } void CTest5::SayHelloMsg() { AfxMessageBox(_T("Hello Test5")); } //测试CTest02,CTest05 #include "Test5.h" class AFX_EXT_CLASS CTestAll { public: CTestAll(void); virtual ~CTestAll(void); public: void TestConsole() { new CTest2; CTest2* pTest2=CTest2::GetpInstance(); if(pTest2){ pTest2->SayHello(); }else{ std::cout<<"Call Fail 2"<<std::endl; pTest2=CTest2::GetpInstance2(); CTest2::GetpInstance()->SayHello(); } new CTest5; CTest5* pTest5=CTest5::GetpInstance(); if(pTest5){ pTest5->SayHello(); }else{ std::cout<<"Call Fail 5"<<std::endl; pTest5=CTest5::GetpInstance2(); CTest5::GetpInstance()->SayHello(); } delete pTest2; delete pTest5; } void TestGui() { new CTest2; CTest2* pTest2=CTest2::GetpInstance(); if(pTest2){ pTest2->SayHelloMsg(); }else{ AfxMessageBox(_T("Call Fail 2")); pTest2=CTest2::GetpInstance2(); CTest2::GetpInstance()->SayHello(); } new CTest5; CTest5* pTest5=CTest5::GetpInstance(); if(pTest5){ pTest5->SayHelloMsg(); }else{ AfxMessageBox(_T("Call Fail 5")); pTest5=CTest5::GetpInstance2(); CTest5::GetpInstance()->SayHello(); } delete pTest2; delete pTest5; } };
MFC console Exe文件,Depends on Dll00,Dll01
C/C++ code
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[]) { int nRetCode = 0; // initialize MFC and print and error on failure if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0)) { // TODO: change error code to suit your needs _tprintf(_T("Fatal Error: MFC initialization failed\n")); nRetCode = 1; } else { CTestAll test; test.TestConsole(); } return nRetCode; }
作者: mcmcmc 发布时间: 2011-12-15
有一行贴错了
template<class Tp> TSingleton<Tp>::TSingleton(Tp* pThis,const std::string& strT):CSingleton(strT)
template<class Tp> TSingleton<Tp>::TSingleton(Tp* pThis,const std::string& strT):CSingleton(strT)
作者: mcmcmc 发布时间: 2011-12-15
Console输出如下
CTest2 created: 1
fail to load class's instance: unknown
Call Fail 2
duplicate!
CTest2 created: 2
GetpInstance() success: unknown
Hello Test2CTest20
CTest5 created: 1
GetpInstance() success: CTest5
Hello Test5
deleted: CTest2
deleted: CTest5
请按任意键继续. . .
CTest2 created: 1
fail to load class's instance: unknown
Call Fail 2
duplicate!
CTest2 created: 2
GetpInstance() success: unknown
Hello Test2CTest20
CTest5 created: 1
GetpInstance() success: CTest5
Hello Test5
deleted: CTest2
deleted: CTest5
请按任意键继续. . .
作者: mcmcmc 发布时间: 2011-12-15
珍惜生命,远离扩展dll,只使用纯C接口的标准dll
作者: taodm 发布时间: 2011-12-15
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28