// 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 << "done\n";
getchar();
}
以下代码在VC9下运行完全正常。但是,在VC6下,我会遇到以下消息立即崩溃。
Debug Assertion失败!
程序: C:\项目\ use_dynamic_link \调试\ use_dynamic_link.exe 文件:dbgheap.c行:1044
表达式: _CrtIsValidHeapPointer(pUserData)
是不允许在VC6下导出auto_ptr?
通过DLL导出STL集合类是一个已知问题。
然而,我谷歌周围并没有看到任何提及std :: auto_ptr。
任何解决方法?
答案 0 :(得分:4)
DLL有自己的堆,所以你必须确保你是新的并从同一个上下文中删除。
答案 1 :(得分:1)
我的第一个猜测是VC9中的exe和dll项目被设置为CRT作为共享dll的目标,而一个或两个VC6项目都是针对静态CRT(非dll)。 / p>
或者,dll和exe都针对共享CRT dll的不同版本(因此它们实际上使用了2个不同的CRT)。
在VC6中,检查C / C ++项目属性的代码生成类别中的运行时库选项。确保exe和dll都定位相同的DLL库选项。
答案 2 :(得分:1)
您违反了ODR(一个定义规则),并且很可能内联成员函数 - 因为它们内联了两个不同的std::auto_ptr
定义,您会得到未定义的行为。
最重要的是,正如Eddy指出的那样,当auto_ptr::~auto_ptr
释放被保持的对象时,它将在EXE中调用operator delete
,而不是在调用operator new
的DLL中调用__declspec(dllexport)
。这种不匹配也会导致崩溃。
一般来说,导出已实现的类(仅由纯虚函数组成的接口类,并为构造导出免费的工厂函数)是非常脆弱的,然后你不要在类上使用{{1}},仅限于工厂功能。
答案 3 :(得分:0)
行。我意识到了根本原因。它是由
引起的DLL内存管理器混音
从DLL分配内存
将指针返回EXE
尝试从EXE中删除指针
步骤(3)将只能正常工作
如果我们静态链接到运行时库,DLL使用的内存管理器可能与EXE使用的内存管理器不同。