0

发布模式工作正常,但调试模式给了我这个:

Executable_to_LinkDLL_to_FDDDLL.exe 中 0x0fc5edac (msvcr90d.dll) 的未处理异常:0xC0000005:访问冲突写入位置 0xbaadf00d。

我正在使用 Octave 发布 DLL。异常如下所示。我想知道是否有人遇到过这个问题。

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

这是我的代码中发生错误的地方(基于以下调用堆栈):

这是我的代码中发生错误的地方

在此处输入图像描述

4

4 回答 4

3

查看 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 运行时的发布或调试版本设置编译器标志)。

所以你有两个问题:

  1. std::stringOctave DLL 和您的应用程序之间的版本之间的二进制兼容性,以及

  2. 确保构建 DLL 和应用程序以使用运行时库的 DLL 版本,以确保使用相同的内存堆。

您使用的解决方案char *仅避免std::string传递引用和对象。我不知道这个解决方案有多可靠,因为似乎很容易出错并std::string在某个时候调用函数。

我只是确保在开发和部署应用程序时使用正确的 DLL。这正是 Microsoft 对其 DLL 所做的事情——您不能在应用程序中混合和匹配 Microsoft DLL 的发布和调试版本,因此这里同样适用。唯一可以混合/匹配发布和调试 DLL 的情况是 DLL 仅使用“简单”类型,如 DWORD、LONG、TSTR 等或指向这些类型的指针作为参数和返回值。

于 2014-08-08T14:39:28.370 回答
2

调试器正在接收对未初始化内存的写入,该内存正被您的程序在发布模式下静默使用。(即在发布模式下,这是一场等待发生的灾难。)0xbaadf00d实际上是一种调试器消息;请参阅此处的相关条目。

如果没有看到您的代码,很难说除此之外问题是什么。

编辑:您发布了调试输出引用--所以代码中的memcpy实例memcpy是一个明显的地方。

于 2014-08-07T20:34:03.380 回答
1

Windows LocalAlloc 用值 0xbaadf00d 标记未初始化的堆内存。看起来您正在从未初始化的源获取指针值并尝试写入该内存位置。虽然这可能在发布模式下“起作用”,但它可能会导致运行较长时间的程序中的内存损坏。

于 2014-08-07T20:34:58.527 回答
0

我通过实现以下代码解决了这个问题。string_vector现在我没有使用 Octave 类,而是使用了一个char*类似的数组,char*argv[2]={"embedded","-q"};因此错误已解决,但我遇到了此链接中提到的另一个错误:Octave c++ and VS2010

在此处输入图像描述

于 2014-08-08T14:22:28.170 回答