在DLL接口中使用boost :: shared ptr可以吗?

时间:2009-12-24 15:08:20

标签: dll boost memory-management shared-ptr

在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都不再引用它时,对象就会被删除。

5 个答案:

答案 0 :(得分:10)

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

  

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

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

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

答案 1 :(得分:4)

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

答案 2 :(得分:2)

DLL通常不拥有资源 - 资源由使用DLL的进程拥有。你可能最好还是返回一个普通指针,然后将其存储在调用端的共享指针中。但是没有更多的信息,很难100%肯定这一点。

答案 3 :(得分:2)

如果从dll接口公开原始指针,需要注意的事项。它强制您使用共享的dll CRT,在一个CRT中分配的内存不能在不同的CRT中解除分配。如果您在所有模块中使用共享dll CRT(dll和exe),那么你很好,它们都共享相同的堆,如果你没有穿过CRT,那么世界就会崩溃。

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

答案 4 :(得分:0)

不,不是。

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

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