【问题标题】:Is it OK to use boost::shared ptr in DLL interface?在 DLL 接口中使用 boost::shared ptr 可以吗?
【发布时间】:2009-12-24 15:08:19
【问题描述】:

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

【问题讨论】:

    标签: dll boost memory-management shared-ptr


    【解决方案1】:

    根据有效 C++(第 3 版)中的 Scott Meyers,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 兼容了。

    【讨论】:

    • 注意:如果您要链接静态 CRT,您将遇到问题。每个静态链接到 CRT 的模块都有自己的堆。如果所有模块都链接到 DLL CRT,那么它们都将共享一个堆。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

        • 如何确保 exe 和 dll 使用共享 dll CRT?什么是编译器标志?
        【解决方案5】:

        不,不是。

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-07-26
          • 2014-03-02
          • 1970-01-01
          • 2011-03-04
          • 1970-01-01
          • 2011-01-16
          • 2010-12-09
          • 1970-01-01
          相关资源
          最近更新 更多