我遇到了由于我的dll和我的实际项目中的不同CRT设置(MTd MDd)而导致的堆腐败。 我发现奇怪的是,当我将dll中的析构函数设置为虚拟时,应用程序只会崩溃。 有没有一个简单的解释呢?我知道我不能释放那些不在我的堆上的内存,但是当我将析构函数定义为非虚拟的时候,其中的差异究竟在哪里。CRT虚拟析构函数
一些代码只是为了更清晰一点
的DLL
#pragma once
class CTestClass
{
public:
_declspec(dllexport) CTestClass() {};
_declspec(dllexport) virtual ~CTestClass() {};
};
而且我的项目
int main(int argc, char* argv[])
{
CTestClass *foo = new CTestClass;
delete foo; // Crashes if the destructor is virtual but works if it's not
}
此外,你是否有同样的问题,通过将declspec移动到* class *('class _declspec(dllexport)CTestClass {...}')并删除每个成员declspecs?只是好奇。注意,调用代码和DLL应该使用相同的CRT(调试或发布),因此需要考虑。我甚至不确定混合模式是否受支持(我不认为它是)。 – WhozCraig
您的流程中有多个CRT副本。你只导出类方法,而不是v表。试图理解这一切如何相互作用来轰炸你的代码并不是那么有效,这是可以预料的。使用虚拟方法导出类需要导出整个类,并将__declspec(dllexport)放在* class *关键字旁边。而且您必须确保使用单个分配器来创建和销毁该对象。很难保证,除非你始终用/ MD编译并使用完全相同的编译器版本。在模块边界上暴露C++类是有风险的。 –
你是对的,即使我找出为什么它不起作用,它不会帮助我太多。感谢你的想法:) – Poisonbox