【问题标题】:Can classes like QString be safely transferred across DLL boundaries, assuming the same compiler?假设使用相同的编译器,像 QString 这样的类可以安全地跨 DLL 边界传输吗?
【发布时间】:2016-09-15 13:51:14
【问题描述】:

我知道在 C++ 中编写(动态)插件时,插件分配的内存也应该由插件释放。显然,这同样适用于一般的 DLL。

以下假设:可执行文件、所有插件和所有依赖项(如 Qt)将始终使用相同的编译器构建

由于像QString 这样的类使用浅拷贝等机制,因此使用内部数据指针:

如果插件通过(浅)副本将本地定义的QString 返回到可执行文件,并且副本超出了可执行文件的范围,是否会在错误的进程中释放内存?

示例代码:

// Defined in a DLL which is loaded at runtime
class SamplePlugin : IPlugin
{
public:
    QString getSomeStringData() const override
    {
        return "Hello World"
    }
}

// Defined in the executable
void Test( PluginManager* pluginManager )
{
    for( auto plugin : pluginManager->loadPlugins() )
    {
        auto stringData = plugin->getSomeStringData();
        doSomethingWith( stringData )

    } // stringData goes out of scope here - is this a problem?
}

【问题讨论】:

    标签: c++ qt memory-management dll


    【解决方案1】:

    一般来说,2个Dll可能会共享对象如果

    1. 一个分配的内存可以被另一个安全删除(即它们共享相同的共享运行时[和任何其他依赖库])。

    2. 两者中的代码已使用相同的编译器和兼容的编译器选项进行编译。

    3. 对象不依赖于共享库本地的任何静态状态,或者

    4. 已根据需要将对象标记为 DllExport/Import。

    请注意,即使满足以上所有条件,并且 2 个 Dll 中的对象依赖于同一个静态库,您也可能会遇到问题(如果该静态库具有全局链接的状态,例如静态变量)。

    【讨论】:

      猜你喜欢
      • 2021-09-09
      • 1970-01-01
      • 1970-01-01
      • 2012-12-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多