c++ - 在动态库中链接时如何解析符号

标签 c++ dynamic dll linker shared-libraries

有些东西我还没有完全吸收。我的几乎所有开发都涉及静态生成和编译代码,而不使用链接动态库(dll 或 .so)。

在这种情况下,我了解编译器和链接器如何在单步执行代码时解析符号。

但是,例如在动态库中链接时,并且动态库是使用与主代码不同的编译器编译的,符号名称不会不同吗?

例如,我在主代码中定义了一个名为“RequiredData”的结构,如下所示。想象一下 FuncFromDynamicLib() 函数是单独动态库的一部分,并且它采用相同的结构 requiredData 作为参数。意思是在动态库的某个地方,必须重新定义这个结构体?这些结构是相同的,动态链接时如何解决这个问题。如果数据成员不同怎么办?提前致谢。

#include <iostream>

using namespace std;

struct RequiredData
{
    string name;
    int value1;
    int value2;
};

int FuncFromDynamicLib(RequiredData);


int main()
{
    RequiredData data;
    data.name = "test";
    data.value1 = 120;
    data.value2 = 200;

    FuncFromDynamicLib(data);
    return 0;
}


//------------Imagine that this func is Part of dynamic library in another file--------------------
int FuncFromDynamicLib(RequiredData rd)
{
    cout<<rd.name<<endl;
    cout<<rd.value1<<endl;
    cout<<rd.value2<<endl;
}
//------------------------------------------------------

最佳答案

您说得完全正确,一般来说您不能混合使用您的工具。 “链接”的过程没有标准化或指定,因此通常您必须在整个过程中使用相同的工具链,否则实际上一部分将不知道另一部分如何调用目标代码中的符号。

问题实际上更糟:不仅符号名称必须匹配,而且调用约定也必须匹配:如何传播函数参数、返回值、异常以及如何处理 RTTI 和动态转换。

所有这些因素都总结在术语“应用程序二进制接口(interface)”(简称 ABI)下。而你描述的问题可以概括为“没有标准的ABI”。

有几个因素使情况不再那么可怕:

  • 对于 C 代码,每个主要平台都作为大多数工具遵循的事实上标准 ABI。因此,C 代码实际上具有高度的可移植性和互操作性。

  • 对于 C++ 代码,ABI 比 C 代码复杂得多。但是,对于 x86 和 x86-64 这两个主要平台,安腾 ABI 被用于多种平台,这至少创建了具有某种互操作性的环境。特别是,ABI 的名称修改规则(即如何将命名空间限定名称和函数重载集表示为平面字符串)是众所周知的,并且拥有广泛的工具支持。

对于 C++,还有更多特殊的问题。将编译后的代码发送给客户是一回事,但另一个问题是大部分 C++ 库代码都位于 header 中并且每次都会进行编译。因此,问题不仅在于您可能使用不同的编译器,还在于不同的库实现。类布局的内部细节变得相关,因为您不能像访问供应商 B 的 vector 一样访问供应商 A 的 vector 。 GCC 将此称为“库 ABI”。

关于c++ - 在动态库中链接时如何解析符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42915905/

相关文章:

Java 动态名称

java - 从动态库调用 jni 时 JVM 堆内存不足

使用递归回溯的 C++ 数独求解器不起作用

c++ - 如何在visual studio上过滤调试输出窗口?

c++ - 为什么 fetch_sub 不是释放操作?

c++ - 是否可以将纯虚函数覆盖到模板?

mysql - 动态行未使用 Laravel Controller 保存在数据库中

jQuery 不响应简单的 .click() 命令——出了什么问题?

Python,何时使用 ctypes.byref 作为引用传递

c# - 公开引用的类型(类)而不需要额外的引用