在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都不再引用它时,对象就会被删除。
答案 0 :(得分:10)
根据Scott Meyers的Effective C ++(第3版),shared_ptrs在dll边界上是安全的。 shared_ptr对象从创建它的dll中保存一个指向析构函数的指针。
不过,蒂姆·莱瑟(Tim Lesher)有一个值得关注的问题,他提到here。您需要确保在shared_ptr最终超出范围之前未卸载创建shared_ptr的DLL。我会说,在大多数情况下,这不是你必须注意的事情,但如果你正在创建松散耦合的dll,那么我建议不要使用shared_ptr。他在第18项的书中指出,“这是一个特别好的特征 tr1 :: shared_ptr是它自动使用其每指针删除器 消除另一个潜在的客户端错误,“交叉DLL问题”。 使用new in one创建对象时会出现此问题 动态链接库(DLL),但在不同的DLL中删除。上 许多平台,这样的跨DLL新/删除对导致运行时 错误。 tr1 :: shared_ptr避免了这个问题,因为它的默认删除器 使用从创建tr1 :: shared_ptr的同一DLL中删除。“
另一个潜在的缺点是确保双方都使用兼容版本的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 =普通旧数据”概念相关)类型可以安全地在单独构建的模块之间传递。