如何在 DLL 中返回向量?

Posted

技术标签:

【中文标题】如何在 DLL 中返回向量?【英文标题】:How to Return a vector in a DLL? 【发布时间】:2011-03-21 03:33:18 【问题描述】:

我为我的应用程序开发了一个插件系统。 我的软件是用MFC/c++编写的

我选择从 DLL 导入函数。 但我面临一个问题。 我曾使用 std 库编写,但 SO 向我表明“如果基于模板将任何内容传入和传出 DLL 时存在危险”

所以我开始重写它。但现在我找不到一个好的解决方案。 此 dll 将解析 Youtube 并以如下结构返回结果:

struct VideoInfo
wchar_t* strName;
wchar_t* strURL;
int iDuration;
float fRate;
;

但将是其中的 50 个,在我之前的代码中,我刚刚返回了一个 std::vector<VideoInfo*> *vecVideos;,但我怎样才能以安全的方式做到这一点?

【问题讨论】:

如果你的向量类型与被调用者的向量类型不兼容,你也会遇到问题。例如,如果您在编译时将 _SECURE_SCL 设置为 0,而被调用者将该宏设置为 1(假设为静态链接)。我以前也被类似的东西咬过。 【参考方案1】:

您可以创建一个链表并返回它,而不是返回一个向量。

不用担心不兼容,使用简单:

struct Node

    VideoInfo vi;
    Node *Next;
;

在构建视频列表时,只需执行以下操作:

Node *ptr = new Node();
ptr->vi = MyVideoInfo; // Assumes MyVideoInfo is the new video
ptr->Next = current;
current = ptr; // Assuming current is our current linked list

您甚至可以在 c 中使用它,因为您只需要将它包装在 extern "C" 中并将 typedef 添加到节点声明的前面。

【讨论】:

【参考方案2】:

只有当 DLL 和 EXE 不是使用相同的项目配置构建、使用 /MT 而不是 /MD 构建或使用不同版本的运行时库构建时,返回 C++ 对象才是不安全的。在很多情况下,这不是一个实际问题,ymmv。

安全的方法是避免要求 EXE 释放 DLL 从堆中分配的内存。或者反过来。您需要更改初学者的结构,不能有 wchar_t*。您可以编写导出的函数来获取 VideoInfo*,以便调用者可以传递函数填充的缓冲区。

但重申一下,只要 DLL 不存在过时的危险,那么 std::vector 和 std::wstring 就不会有问题。

【讨论】:

如果 DLL 返回未在 EXE 中实例化的模板类型怎么办? @user - 根据我的帖子中提到的注意事项,这不一定是问题。它只会在两个项目都使用声明模板的相同标头时构建,模板在主流编译器中没有外部链接。 std::vector 也是模板类型。

以上是关于如何在 DLL 中返回向量?的主要内容,如果未能解决你的问题,请参考以下文章

如何在带有 Visual Studio 的 dll 导出类中使用唯一指针向量

如何正确导出 DLL 中的矢量

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

如何在 Java 代码中使用从 .dll 使用和返回对象的函数?

如何在 C++ 中返回从零开始的向量索引

如何从返回向量的函数中获取向量值?