在VC6 DLL中的ptr导致崩溃
// dll
#include <memory>
__declspec(dllexport) std::auto_ptr<int> get();
__declspec(dllexport) std::auto_ptr<int> get()
{
return std::auto_ptr<int>(new int());
}
// exe
#include <iostream>
#include <memory>
__declspec(dllimport) std::auto_ptr<int> get();
int main() {
{
std::auto_ptr<int> x = get();
}
std::cout << "donen";
getchar();
}
下面的代码在VC9下完全可以正常运行。 但是,在VC6下,我将遇到以下消息的立即崩溃。
调试断言失败!
程序:C: Projects use_dynamic_link Debug use_dynamic_link.exe文件:dbgheap.c行:1044
表达式:_CrtIsValidHeapPointer(pUserData)
是不是允许在VC6下导出auto_ptr?
这是一个已知的问题,即通过DLL导出STL集合类。
在不同的DLL或EXE中通过指针或引用访问STL对象时访问冲突
但是,我谷歌周围,并没有看到任何提及std :: auto_ptr。
任何解决方法?
一个DLL有自己的堆,所以你必须确保你是新的,并从同一个上下文中删除。
我的第一个猜测是,VC9中的exe和dll项目是为了将CRT设置为共享dll而设置的,而其中一个或两个VC6项目都是针对静态CRT(非dll)。
另外,dll和exe都是针对不同版本的共享CRT dll(因此它们实际上使用2个不同的CRT)。
在VC6中,检查C / C ++项目属性的代码生成类别中的运行时库选项。 确保exe和dll都以相同的DLL库选项为目标。
您违反了ODR(一个定义规则),并且很可能会将内联函数内联 - 因为它们被内联了两个不同的std::auto_ptr
定义,您将得到未定义的行为。
最重要的是,正如Eddy指出的那样,当auto_ptr::~auto_ptr
释放所持有的对象时,它将在EXE中调用operator delete
,而不是调用operator new
的DLL。 这种不匹配也会导致崩溃。
一般来说,导出已实现的类(纯粹由纯虚函数组成的接口类,以及导出用于构建的免费工厂函数)是可以的,然后您不要在类上使用__declspec(dllexport)
,只能在工厂功能。