当前位置: 首页 > 面试题库 >

如何从共享库中导出符号

鞠宏恺
2023-03-14
问题内容

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

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

如果不创建共享库,而是创建具有相同源文件的静态库,然后与该应用程序链接,然后执行该应用程序,则可以正常运行。

所以我的问题是:

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

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

  3. 静态库是如何工作的,即在使用静态库的情况下如何进行地址说明和解析?


问题答案:

这是在Linux上的工作方式:

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

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

3)静态链接是在链接时(在编译后)执行的。实际地址在程序集中被替换,它们是直接调用。

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



 类似资料:
  • 问题内容: 使用GCC,如何在创建共享库后从共享库中删除符号?如果我在C中使用三个文件来处理符号,例如: 和 和 然后我像这样编译并运行: 我怎样才能让这个不再具有象征我已经创建后?我希望使用中定义而不是 从中 删除符号。之后从删除,再运行应该产生的打印输出: 在这个玩具示例中,我知道用and 编译时可以简单地对库名称进行重新排序,但是实际上如何从中删除符号呢?我想象在从中删除后,nm输出的这个g

  • 问题内容: 我有一个共享的对象(dll)。我如何找出所有从中导出的符号? 问题答案: 您是否有“共享库”(通常是AIX上的共享库),UNIX共享库或Windows DLL?这些都是不同的东西,您的问题将它们全部融合在一起:-( 对于AIX共享对象,请使用。 对于ELF共享库,请使用或(如果您有GNU nm)。 对于非ELF UNIX共享库,请说明您对 哪个 UNIX感兴趣。 对于Windows D

  • 问题内容: 从共享库/ dll调用函数的最简单,最安全的方法是什么?我对在Linux上执行此操作最感兴趣,但是如果有一种与平台无关的方法会更好。 有人可以提供示例代码来显示如何在用户将自己的版本编译到共享库的情况下执行以下工作吗? 顺便说一句,我知道如何编译共享库(),我只需要知道一种在运行时加载它的简单方法。 问题答案: 注意: 您正在库调用周围传递C 对象(在这种情况下为STL字符串)。有 *

  • 问题内容: 两个共享库liba.so和libb.so。liba.so使用libb.so。所有c文件都使用-fPIC编译。链接使用- shared。当我们在liba.so上调用dlopen时,它无法在libb.so中找到符号…我们得到“未定义符号”错误。我们可以dlopen libb.so没有错误。我们知道liba正在找到libb,因为我们没有得到文件未找到错误。删除libb.so时,出现文件未找到

  • 我试图从一个位于vars下的新脚本中获取信息,该脚本是从共享库Jenkins类调用的,但出错了。 > 需要-全局配置文件。 目标-能够在共享库中获取全局值,而无需从Jenkins文件发送参数。 文件结构 变量/全局变量。棒极了 shared_library类 詹金斯档案 因此,我可以看到管道中第一次打印的值,但对于第二次打印,我得到: 类:src没有这样的属性:globals。组织。詹金斯。共享图

  • 我有一个CMACE项目,它的下一个结构是: 输出树为: 如果我在linux下编译程序,所有的工作都很完美,但是当我在Windows下做的时候,编译很好,但是app.exe不执行;我得到下一个错误: 我怀疑不要链接internal.cpp,因为当我将它的过程移到internal.h中时,就可以很好地工作。 有什么需要帮忙的吗? 以下是文件:root::cmakelists.txt app::cmak