发布模式工作正常,但调试模式给了我这个:
Executable_to_LinkDLL_to_FDDDLL.exe 中 0x0fc5edac (msvcr90d.dll) 的未处理异常:0xC0000005:访问冲突写入位置 0xbaadf00d。
我正在使用 Octave 发布 DLL。异常如下所示。我想知道是否有人遇到过这个问题。
这是我的代码中发生错误的地方(基于以下调用堆栈):
发布模式工作正常,但调试模式给了我这个:
Executable_to_LinkDLL_to_FDDDLL.exe 中 0x0fc5edac (msvcr90d.dll) 的未处理异常:0xC0000005:访问冲突写入位置 0xbaadf00d。
我正在使用 Octave 发布 DLL。异常如下所示。我想知道是否有人遇到过这个问题。
这是我的代码中发生错误的地方(基于以下调用堆栈):
查看 Octave 文档,使用了对的string_vector
引用std::string
。这意味着需要为您正在开发的编译器和设置构建 Octave 库。
原因是诸如此类的类std::string
不需要与另一个版本的std::string
. 当您在调试版本中使用发布版本时,std::string
发布版本和调试版本的内部结构不同。
但是,即使 的版本std::string
是二进制兼容的,您也有确保 Octave DLL 和您的应用程序使用相同的运行时堆的问题。原因是std::string
使用动态分配的内存,并且必须为 DLL 和应用程序使用相同的堆。为确保这一点,必须使用 Visual Studio 运行时库的 DLL 版本(/MD
或者/MDd
必须分别为 DLL 运行时的发布或调试版本设置编译器标志)。
所以你有两个问题:
std::string
Octave DLL 和您的应用程序之间的版本之间的二进制兼容性,以及
确保构建 DLL 和应用程序以使用运行时库的 DLL 版本,以确保使用相同的内存堆。
您使用的解决方案char *
仅避免std::string
传递引用和对象。我不知道这个解决方案有多可靠,因为似乎很容易出错并std::string
在某个时候调用函数。
我只是确保在开发和部署应用程序时使用正确的 DLL。这正是 Microsoft 对其 DLL 所做的事情——您不能在应用程序中混合和匹配 Microsoft DLL 的发布和调试版本,因此这里同样适用。唯一可以混合/匹配发布和调试 DLL 的情况是 DLL 仅使用“简单”类型,如 DWORD、LONG、TSTR 等或指向这些类型的指针作为参数和返回值。
调试器正在接收对未初始化内存的写入,该内存正被您的程序在发布模式下静默使用。(即在发布模式下,这是一场等待发生的灾难。)0xbaadf00d
实际上是一种调试器消息;请参阅此处的相关条目。
如果没有看到您的代码,很难说除此之外问题是什么。
编辑:您发布了调试输出引用--所以代码中的memcpy
实例memcpy
是一个明显的地方。
Windows LocalAlloc 用值 0xbaadf00d 标记未初始化的堆内存。看起来您正在从未初始化的源获取指针值并尝试写入该内存位置。虽然这可能在发布模式下“起作用”,但它可能会导致运行较长时间的程序中的内存损坏。
我通过实现以下代码解决了这个问题。string_vector
现在我没有使用 Octave 类,而是使用了一个char*
类似的数组,char*argv[2]={"embedded","-q"};
因此错误已解决,但我遇到了此链接中提到的另一个错误:Octave c++ and VS2010