【问题标题】:Distributed dll and c++ objects - how some libraries handle this?分布式 dll 和 c++ 对象 - 一些库如何处理这个?
【发布时间】:2016-02-19 08:53:17
【问题描述】:

最近我发现,如果可执行文件和 dll 是用不同的编译器编译的,甚至是使用不同版本的 same 编译器,甚至是不同的 强>相同编译器!说我很惊讶就是无话可说——一直以来我都认为我可以创建一个动态库并安全地分发它。

现在有了这些知识,我想知道某些库是如何工作的?让我们在 system32 文件夹中获取一个 dll。使用依赖项 Walker,我可以看到,在 d3d11.dll 函数中使用 C 参数公开 - 我猜这是 C 约定,它为我们提供了保证它会工作的保证。我也知道d3d11 可以与COM 对象一起使用,因此不存在在 dll 中创建对象并在 exe 中销毁它的风险。

但是现在让我们使用任何Qt dll - 导出为c++ 的函数,并修改它们的所有名称。我记得当我安装框架时,我指定了我的编译器 - MSVC2013,但我没有指定版本!我可以在update5 编译器中使用用update1 编译器编译的dll,但我不记得有任何奇怪的行为。那么它是如何工作的呢?他们如何处理损坏的函数名称解析、参数传递?

【问题讨论】:

    标签: c++ qt dll


    【解决方案1】:

    windows下的库必须用同一个编译器编译的通常原因是C++标准库在不同版本的MSVC++之间不兼容ABI。如果库跨 dll 边界使用 C++ 标准库,只要库中的 C++ 标准库和使用该库的编译器相同,就可以。

    Qt 公开了自己的字符串(QString)和向量(QVector)等,而不是 std::string 和 std::vector,因此 Qt 不会通过 dll 边界公开 C++ 标准库,因此 Qt dll 可以工作与所有版本的 Visual Studio。

    【讨论】:

    • 谢谢。我阅读了有关 ABI 的信息,许多资源说任何 C++ 对象都不兼容 ABI。此外,如果我理解正确,函数的名称(损坏的名称)可能因编译器而异。这是如何处理的?
    • @nikitablack 是的,我不认为 namemangling 是 C++ 标准的一部分,因此每个编译器都可以使用自己的 mangling。包含 .lib 将告诉编译器 .dll 中存在哪些符号
    • 这很好。因此,为了分发动态库,还必须分发一个库。
    • @nikitablack 没错。 dll 在运行时不需要 .lib,但在编译时确实需要它。但是请注意,静态库在 Windows 上也以 .lib 结尾,这往往会使人们感到困惑,并且包含 .lib 与静态库非常不同。
    • 我不相信这是正确的。在绝大多数情况下,引起麻烦的不是破坏性的 ABI 更改。微软在这方面非常保守。如果这确实是原因,那么 any 用户定义类型将受到影响(std::vectorQVector 一样多)。原因更为普通:分配器在移动 DLL 边界时会丢失重要的上下文。 Potential Errors Passing CRT Objects Across DLL Boundaries 有更多详情。
    猜你喜欢
    • 1970-01-01
    • 2013-03-30
    • 1970-01-01
    • 2021-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多