将向量从 c++ dll 重新调整到另一个 c++ exe 时出现问题

Posted

技术标签:

【中文标题】将向量从 c++ dll 重新调整到另一个 c++ exe 时出现问题【英文标题】:Problem retuning a vector from a c++ dll to another c++ exe 【发布时间】:2009-11-19 14:39:36 【问题描述】:

我在dll A.dll中有一个函数foo(),其定义如下

vector<CustomObject> foo()  
   
      vector<CustomObject> customObjectCollection;

   //code which populates customObjectCollection goes here

return customObjectCollection;   

我指的是来自 exe B 的 dll A 的这个方法向量 foo()

当我从 B 调用函数 foo 时,我得到一个未处理的异常,上面写着

"未处理的异常在 B.exe 中的 0x10487b3f(msvcp90d.dll)" 0xC0000005:访问冲突同时 写入位置 0xfdfdfdfd"。

注意:自定义对象类型不实现复制构造函数

当我尝试通过将 B.exe 附加到 A.dll 进行调试时,我发现在方法向量 foo() 内部,向量被填充没有任何问题,但是当控件返回到 B.exe 时,向量中的阀门没有得到抄袭!!!

此外,如果方法 foo 通过引用返回向量,则不会发生异常,并且 B.exe 会收到一个空向量。

有什么问题??是否因为我没有为 CustomObject 实现复制构造函数而发生。

非常感谢任何帮助 (抱歉没有正确表达问题)

谢谢 杰尔

【问题讨论】:

【参考方案1】:

这是运行时库不匹配的典型症状。您必须确保 EXE 和 DLL 都链接到动态 C++ 库(DLL 版本)。

如果一个(或两个)与静态 C++ 运行时(LIB 版本)链接,您将遇到内存冲突,因为运行时库的两个实例具有不同的地址空间。

【讨论】:

【参考方案2】:

首先,您不应该返回对堆栈上声明的本地对象的引用。 第二:对元素有要求才能在 STL 容器中使用 1) 复制构造函数 2) 赋值运算符 3) 公共析构函数 还有更多特定于容器的内容(例如关联容器的排序标准)。 将创建复制构造函数以及赋值运算符(感谢编译器),因此除非您明确隐藏它们 - 您的对象拥有它们(如果您没有复制构造函数,编译器会抱怨)。 但是这些隐式的拷贝构造函数和赋值运算符可能不够聪明,所以你可能想自己实现。例如:假设您在构造函数中的 CustomObject 使用 new 创建了某个类的实例,并将其保存为要在析构函数中销毁的指针。默认复制构造函数将进行浅拷贝,因此这将导致两个对象持有相同的指针。一旦其中一个被销毁,第二个就变得不一致(它持有已经被释放的指针)。

最后一点:尽量不要按值返回向量。涉及大量复制。在堆栈上的调用者中声明它并将其作为引用传递给您foo

【讨论】:

感谢大家的回答 :) .... 我在 A.dll 中使用函数 foo() 并且它工作正常,但是当我尝试在不同的 dll 或 exe 中使用它时它失败了! !! 那么(正如其他人已经回答的那样)它可能与链接有关。【参考方案3】:

可能最安全的方法是:

bool foo(vector<someclass*> &customObjectCollection)

    //code which populates customObjectCollection goes here

    return success

调用程序这样创建和维护向量,因此不需要复制。来电者会这样做

vector<someclass *> customObjectCollection;
foo(customObjectCollection);

另外,根据您的具体操作,请注意使用 someclass 指针向量而不是 someclass 对象。

【讨论】:

【参考方案4】:

这里有很多可能性,但您没有告诉我们足够多的信息来确定最有可能应用的可能性。

一种可能性是将代码放入 DLL 中是(半)唯一的。如果你静态链接标准库,每个模块(EXE、DLL)都有自己的内存管理,包括它自己的堆,所以很多试图在一个模块和另一个模块之间转移内存所有权的操作都会失败(看似)奇怪原因。解决此类问题的方法通常是链接到所有模块的 DLL 中的标准库。这提供了一个整个应用程序共享的标准库副本,因此在模块之间传递所有权不会导致问题。

另一种可能性是您的CustomObject 类没有正确处理复制。由于您没有告诉我们有关其内部结构的任何信息,因此我们无法猜测您可能需要在这里做什么。

【讨论】:

嗨,杰瑞,感谢您提供的信息...... CustomObject 类看起来像这样...... class CustomObject string name;字符串路径;矢量 能力; //getter setter 方法 //该类没有明确定义的构造函数或析构函数 在这种情况下,(到目前为止)首先要尝试的是链接基于 DLL 的标准库。

以上是关于将向量从 c++ dll 重新调整到另一个 c++ exe 时出现问题的主要内容,如果未能解决你的问题,请参考以下文章

如何重新调整多维向量的大小? C++ [重复]

从 C++ dll 编组导出的字符串向量

如何在 C++ 中将一个对象从一个向量复制到另一个向量?

从 python ctypes 中的 c++ dll 传递向量

为啥 C++ 中的向量不会自动调整大小

如何在 C++ 中将两个向量复制到另一个向量