10

在 C++ 中开发一个返回 boost 共享指针并将它们用作参数的 DLL 是否有效?

那么,这样导出函数可以吗?

1.) boost::shared_ptr<Connection> startConnection();
2.) void sendToConnection(boost::shared_ptr<Connection> conn, byte* data, int len);

特别是:引用计数是否跨 DLL 边界工作,或者要求 exe 和 dll 使用相同的运行时?

目的是克服对象所有权的问题。因此,当 dll 和 exe 不再引用它时,该对象将被删除。

4

5 回答 5

11

根据有效 C++(第 3 版)中的 Scott Meyers,shared_ptrs 跨 dll 边界是安全的。shared_ptr 对象从创建它的 dll 中保存指向析构函数的指针。

在他的书第 18 条中,他指出,“tr1::shared_ptr 的一个特别好的特性是它自动使用它的每个指针删除器来消除另一个潜在的客户端错误,即“跨 DLL 问题”。对象是在一个动态链接库 (DLL) 中使用 new 创建的,但在另一个 DLL 中被删除。在许多平台上,这种跨 DLL 的新/删除对会导致运行时错误。tr1::shared_ptr 避免了这个问题,因为它的默认删除器使用从创建 tr1::shared_ptr 的同一 DLL 中删除。"

不过,蒂姆·莱舍 (Tim Lesher) 有一个有趣的问题需要注意,他在这里提到了这一点。您需要确保在 shared_ptr 最终超出范围之前未卸载创建 shared_ptr 的 DLL。我想说,在大多数情况下,这不是您必须注意的事情,但如果您正在创建松散耦合的 dll,那么我建议您不要使用 shared_ptr。

另一个潜在的缺点是确保双方都是使用兼容版本的 boost 库创建的。Boost 的 shared_ptr 已经稳定了很长时间。至少从1.34开始,它就与 tr1 兼容。

于 2011-11-10T19:03:35.643 回答
4

在我看来,如果它不在标准中并且它不是您的库提供的对象/机制,那么它不应该成为库接口的一部分。您可以创建自己的对象来进行引用计数,也可以在下面使用 boost,但它不应该在界面中显式公开。

于 2009-12-24T15:23:00.523 回答
2

DLL 通常不拥有资源 - 资源归使用 DLL 的进程所有。您最好返回一个普通指针,然后将其存储在调用方的共享指针中。但如果没有更多信息,很难 100% 确定这一点。

于 2009-12-24T15:21:56.190 回答
2

如果您从 dll 接口公开原始指针,则需要注意一些事项。它迫使您使用共享 dll CRT,在一个 CRT 中分配的内存不能在另一个 CRT 中释放。如果您在所有模块(dll 和 exe)中使用共享 dll CRT,那么您很好,它们都共享同一个堆,如果您不使用,您将跨越 CRT,世界将崩溃。

除了这个问题,我同意接受的答案。创建工厂可能不应该为客户端代码定义所有权和生命周期管理。

于 2010-01-05T08:57:00.597 回答
0

不它不是。

boost::shared_ptr<T>DLL 边界两侧的布局可能不同。(布局受编译器版本、打包编译指示和其他编译器选项以及 Boost 源代码的实际版本影响。)

只有“标准布局”(C++11 中的一个新概念,与旧的“POD = 普通旧数据”概念相关)类型可以安全地在单独构建的模块之间传递。

于 2014-08-08T14:51:04.353 回答