彻底崩溃的VS2005 DLL之Singleton模板
继承自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
//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
//测试体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
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;
}
相关推荐
.NET Web开发路线图:从WebForms到Minimal API的演进与实战
ASP.NET Web开发是一套随运行时、I/O模型和部署范式持续演进的技术体系。其核心原理在于框架如何抽象HTTP生命周期、管理状态契约与协调组件协作。技术价值体现在性能跃升(如Kestrel异步I/O带来QPS翻三倍)、运维简化(Docker容器固化运行时边界)与故障收敛(Middleware洋葱模型提升可观测性)。典型应用场景覆盖电商后台、政务中台、IoT设备接入等中大型系统,尤其在需平衡开发效率与生产稳定性的.NET生态项目中,ASP.NET Core、Minimal API、JWT认证与EF Co
弱电网下光伏并网逆变器序阻抗建模仿真复现扫频法【序阻抗判断稳定性】
内容概要:本文聚焦于弱电网条件下光伏并网逆变器的序阻抗建模与稳定性分析,系统阐述了基于扫频法的阻抗特性仿真与复现方法。通过构建正负序阻抗模型,深入剖析逆变器在弱电网环境中的动态响应特性,结合锁相环、电流环等关键控制环节对系统阻抗的影响机制,采用序阻抗稳定性判据评估多机并网或复杂电网条件下的系统稳定裕度。研究在Simulink平台中实现激励信号注入、频率响应采集与阻抗曲线绘制,为高比例新能源接入背景下并网系统的稳定性分析提供了可靠的仿真手段与理论支撑,尤其适用于SCI级别论文成果的复现与拓展验证。; 适合人群:电力电子、新能源并网技术及相关领域的硕士/博士研究生、科研人员,以及从事光伏逆变器、微电网稳定控制开发的工程技术人员。; 使用场景及目标:①掌握扫频法在电力电子装置阻抗建模中的具体实施流程;②理解并应用基于序阻抗的稳定性判据进行系统稳定边界分析;③用于高水平学术论文(如SCI期刊)中阻抗建模与稳定性分析部分的仿真复现与方法验证; 阅读建议:建议读者结合文中所述方法与提供的参考文献,自主搭建Simulink仿真模型,逐步完成扰动信号设计、数据采集、傅里叶分析及阻抗拟合全过程,深入探究控制参数变化对系统阻抗特性和稳定性的具体影响,强化理论与实践的融合能力。
三相并网逆变器虚拟阻抗+统一有源阻尼策略SVPWM+SPWM调制仿真
内容概要:本文档系统性地介绍了三相并网逆变器的核心控制技术及其在复杂电网环境下的仿真应用,重点涵盖虚拟阻抗与统一有源阻尼策略在SVPWM和SPWM调制方式下的实现方法,旨在提升逆变器的稳定性与电能质量。内容包括无功功率扰动孤岛检测、中点电位平衡控制、低电压穿越(LVRT)、模型预测控制(MPC)、正负序分离、电网前馈控制等关键技术,并扩展至风储联合调频、微电网下垂控制、虚拟同步发电机(VSG)、构网型逆变器等多种典型电力系统应用场景。所有技术均配有基于Simulink/Matlab平台的完整仿真模型、参考文献及说明文档,强调理论分析与仿真实践的深度融合,突出科研中“借力”与创新思维的重要性。; 适合人群:电气工程、自动化、新能源等相关专业的研究生、科研人员及从事电力电子与可再生能源系统开发的工程师;具备MATLAB/Simulink仿真基础和电力系统专业知识的技术人员。; 使用场景及目标:①开展三相并网逆变器控制策略的研究与优化设计;②复现高水平学术论文中的控制算法;③完成毕业课题、科研项目或工程仿真验证;④掌握虚拟阻抗、有源阻尼、SVPWM/SPWM调制、MPC、VSG等核心技术的建模与实现方法;⑤支撑微电网、构网型变流器等前沿方向的科研攻关。; 阅读建议:建议按照资源目录结构化学习,优先选择与自身研究方向契合的内容模块,结合提供的仿真模型、参考文献和说明材料进行实操演练,注重从理论推导到仿真实现的全过程理解,充分利用共享网盘资源深化技术掌握,提升科研效率与创新能力。
chromedriver-win32-159.0.8133.0(Canary).zip
chromedriver-win32-159.0.8133.0(Canary).zip
计算机“101计划”《人工智能引论》教学大纲+课件+实训案例
计算机“101计划”《人工智能引论》教学大纲+课件+实训案例


