linux - 如何从共享库导出符号

标签 linux shared-libraries arm cross-compiling rvds

我在 Windows 主机上使用 RVDS 编译器使用 *.o 目标代码文件(C 源代码)创建了一个共享库 (*.so)。

我将此共享对象与应用程序链接(使用 gcc 用于 Linux 主机上的 ARM 目标)并获取可执行文件,该可执行文件在运行时会生成段错误。 (我知道我必须调试它!)

如果我不创建共享库,而是创建一个具有相同源文件的静态库,然后链接到应用程序,然后执行应用程序,它会按预期正常工作。

所以我的问题是:

  1. 我是否需要使用某些结构在我的源文件中明确地导出符号(导出到应用程序的函数)或任何其他符号,以便它在与应用程序链接时能够正常工作?需要什么以及我该怎么做?

  2. 共享库是如何工作的?即函数将被加载和运行的地址是否会在创建库时在库中给出。应用程序(main())如何解析要执行库函数的地址?

  3. 静态库是如何工作的,即在静态库的情况下,地址规范和解析是如何发生的?

最佳答案

这是它在 linux 上的工作方式:

1) 不,您不需要做任何事情。但是,您可以使用 gcc -fvisibility 命令行参数限制导出变量,并使用可见性属性显式标记导出的条目。

2) 可执行文件将有一个表,其中包含它导入的所有函数(这些都是具有默认可见性的函数)。加载器/链接器将选择一个地址来加载库并在运行前填充此表,对这些函数的调用是间接调用。 (请注意,这也适用于共享对象)

3) 静态链接在链接时执行(在编译之后)。实际地址在程序集中代入,是直接调用。

注意:有一种叫做 PIC(位置无关代码)的东西。 AFAIK,这涉及对同一共享对象中数据/函数的引用,因此链接器在加载库时不需要覆盖库的一半代码,因为代码不会对其进行任何绝对引用自己的数据。您可以尝试用它进行试验。

关于linux - 如何从共享库导出符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/756174/

相关文章:

c - syncfs 是否等到光盘写入完成?

c - 使 `gcc' 需要 : *** No rule to make target `libmy.so' , 。停止

linux - 为什么 ~ 在 awk 中用双引号引起语法错误

linux - 信号 15 终止

linux - 以粗体显示目录 – 如何启用?与.bash_profile?

.net - 无法在线将 SaveBinaryDirect 与 Sharepoint 一起使用总是返回 403

c++ - 在 Mac OS X 上以多态方式捕获 -fno-rtti 共享库中的异常

Android:为 ARMv7 外部构建 kexec - 错误包括 'expected ' =', ' ,', ' ;', ' asm' 或 '__attribute__' token 之前的 '*'

Android 电视盒在 10 秒内关闭我的应用程序

c++ - C 和 C++ 之间的全局变量