c++ - 为什么在从 dll 内部调整 vector 大小时会出现堆损坏?

标签 c++ dll heap-corruption xll

我正在编写调用 DLL 函数的 XLL(使用 XLW 库)。此 DLL 函数将获取 vector 引用、修改 vector 并通过参数返回它。

我有一个 VS10 解决方案,其中包含几个 c++ 项目、一些 DLL 和一个将从 excel 调用 DLL 函数的 XLL。我使用 VS10 编译器编译所有内容,使用 _HAS_ITERATOR_DEBUGGING=0_CRT_SECURE_NO_WARNINGS 并为所有项目使用相同的运行时库 (/MDd)。

我还必须重建 XLW 库以符合我必须在我的项目中使用的 _HAS_ITERATOR_DEBUGGING=0

当调用 xll_function 时,我遇到了堆损坏错误,但无法弄清楚原因。 在我尝试在调用 dll 函数之前调整 vector 大小之后,错误就消失了。也就是说,我可以调用该函数并获得由参数返回的正确 vector ,并且没有堆损坏。

有人可以阐明这一点吗? 由于我是使用 DLL 的新手,所以我不确定是否会发生这种情况,或者我是否做错了什么。

正如您在下面的代码中看到的,dll 函数将尝试调整 forwards 的大小,我认为这就是产生堆错误的地方。 我试图理解为什么会发生这种情况以及这种调整大小和分配如何适用于 dll。也许我无法调整分配在另一个堆中的 vector 的大小。

** 以下代码 - 第一个函数是 dll 项目类中的静态方法,第二个函数导出到 XLL。

void dll_function(double quote, const std::vector<double>& drift, const std::vector<double>& divs, std::vector<double>& forwards)
{
    size_t size = drift.size();
    forwards.resize(size);

    for( size_t t = 0; t < size; t++)
    {
        forwards[t] = (quote - divs[t]) * drift[t];
    }
}


MyArray xll_function(double quote, const MyArray& drift, const MyArray& divs)
{
    // Resizing the vector before passing to function
    std::vector<double> forwards(drift.size());

    dll_function(quote, drift, divs, forwards);

    return forwards;
}

最佳答案

要跨 DLL 边界传递对 std::vector 或其他 C++ 集合的引用,您需要执行以下操作。

  1. 对两个模块使用相同的 C++ 编译器和相同版本的编译器。

  2. 在项目设置中,为设置 General/Platform Toolset 设置相同的值。

  3. 在项目设置中,将 C/C++/代码生成/运行时库值设置为“多线程 DLL (/MD)”,或用于调试配置的多线程调试 DLL (/MDd)。如果其中一个项目有一个需要静态 CRT 设置的依赖项,抱歉你运气不好,它不会工作。

  4. 在两侧使用相同的配置:如果您构建了 DLL 的调试版本,请不要链接到使用 EXE 的发布版本。也不要更改预处理器定义,例如 _ITERATOR_DEBUG_LEVEL 或 _SCL_SECURE_NO_WARNINGS,或者如果您更改了,请将它们更改为两个项目的相同值。

造成这些复杂情况的原因是 C++ 没有标准化的 ABI。 std::vector 和其他类的内存布局会根据很多事情发生变化。运算符 newdelete 也在 C++ 标准库中,即你不能在一个模块中使用 C++ 分配内存,在不同的模块中释放内存。

如果您不能满足这些条件,有几种解决方法,这里有一个很好的总结:https://www.codeproject.com/Articles/28969/HowTo-Export-C-classes-from-a-DLL

关于c++ - 为什么在从 dll 内部调整 vector 大小时会出现堆损坏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56684685/

相关文章:

c# - 使用反射的对象实例化适用于 VB.NET,但不适用于 C#

c# - ASP.NET MVC 需要两个不同版本的 Newtonsoft.Json.dll

c++ - 堆损坏 - Vector push_back

c++ - 堆腐败?在我的动态内存中?

c++ - 制作没有依赖的DLL文件

c++ - 堆损坏和随机断点

c++ - 未找到 GetAddrInfo 标识符

c++ - 使用初始化列表初始化 unique_ptr 的容器(续)

c++ - 从文件中删除记录 C++

c++ - 类的 index_sequence 用法