我在 Windows 主机上使用 RVDS 编译器使用 *.o
目标代码文件(C 源代码)创建了一个共享库 (*.so
)。
我将此共享对象与应用程序链接(使用 gcc
用于 Linux 主机上的 ARM 目标)并获取可执行文件,该可执行文件在运行时会生成段错误。 (我知道我必须调试它!)
如果我不创建共享库,而是创建一个具有相同源文件的静态库,然后链接到应用程序,然后执行应用程序,它会按预期正常工作。
所以我的问题是:
我是否需要使用某些结构在我的源文件中明确地导出符号(导出到应用程序的函数)或任何其他符号,以便它在与应用程序链接时能够正常工作?需要什么以及我该怎么做?
共享库是如何工作的?即函数将被加载和运行的地址是否会在创建库时在库中给出。应用程序(
main()
)如何解析要执行库函数的地址?静态库是如何工作的,即在静态库的情况下,地址规范和解析是如何发生的?
最佳答案
这是它在 linux 上的工作方式:
1) 不,您不需要做任何事情。但是,您可以使用 gcc -fvisibility
命令行参数限制导出变量,并使用可见性属性显式标记导出的条目。
2) 可执行文件将有一个表,其中包含它导入的所有函数(这些都是具有默认可见性的函数)。加载器/链接器将选择一个地址来加载库并在运行前填充此表,对这些函数的调用是间接调用。 (请注意,这也适用于共享对象)
3) 静态链接在链接时执行(在编译之后)。实际地址在程序集中代入,是直接调用。
注意:有一种叫做 PIC(位置无关代码)的东西。 AFAIK,这涉及对同一共享对象中数据/函数的引用,因此链接器在加载库时不需要覆盖库的一半代码,因为代码不会对其进行任何绝对引用自己的数据。您可以尝试用它进行试验。
关于linux - 如何从共享库导出符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/756174/