Linux 如何从共享库导出符号
我在Windows主机上使用RVDS编译器,使用对象代码文件(C源代码)创建了一个共享库(Linux 如何从共享库导出符号,linux,shared-libraries,arm,cross-compiling,rvds,Linux,Shared Libraries,Arm,Cross Compiling,Rvds,我在Windows主机上使用RVDS编译器,使用对象代码文件(C源代码)创建了一个共享库(*.so) 我将这个共享对象与一个应用程序链接(在Linux主机上为ARM目标使用gcc)并获得一个可执行文件,该文件在运行时会生成分段错误。(我知道我必须调试它!) 与创建共享库不同的是,如果我创建一个具有相同源文件的静态库,然后链接应用程序,然后执行应用程序,那么它就可以正常工作 因此,我的问题是: 我是否需要在源文件中使用一些构造明确地导出符号(导出到应用程序的函数)或任何其他符号,以便在与应用程序链
*.so
)
我将这个共享对象与一个应用程序链接(在Linux主机上为ARM目标使用gcc
)并获得一个可执行文件,该文件在运行时会生成分段错误。(我知道我必须调试它!)
与创建共享库不同的是,如果我创建一个具有相同源文件的静态库,然后链接应用程序,然后执行应用程序,那么它就可以正常工作
因此,我的问题是:
main()
)如何解析要执行库函数的地址以下是它在linux上的工作方式: 1) 不,你什么都不用做。但是,您可以使用gcc
-fvisibility
命令行参数限制导出变量,并使用visibility属性显式标记导出的条目
2) 可执行文件将有一个包含其导入的所有函数的表(这些都是具有默认可见性的函数)。加载程序/链接程序将选择一个地址来加载库,并在运行之前填充此表,对这些函数的调用是间接调用。(请注意,这也适用于共享对象)
3) 静态链接是在链接时间(编译之后)执行的。实际地址在程序集中被替换,它们是直接调用
注意:有一个叫做PIC(位置独立代码)的东西。顺便说一句,这涉及到对同一共享对象中的数据/函数的引用,因此链接器在加载库时不需要覆盖库的一半代码,因为代码不会对自己的数据进行任何绝对引用。你可以试试看。你知道车祸的原因吗 如果您正在动态加载共享库(例如,通过
dlopen()
),一种可能性是您假设库加载正常,但实际上没有加载,然后尝试通过空指针执行函数
gcc
导出符号,因为默认情况下它会导出所有符号;然而,差饷物业估价署可能会,也可能不会这样做。检查您的RVDS编译器文档(尝试将其配置为“”输出?)gcc -shared -o libfoo.so libfoo.a
如果这有帮助,那么RVDS的共享库链接器(或其配置)可能已损坏。@Jonathan:我没有使用dlopen()调用加载共享库。好的-我没有主意了。我更熟悉Unix/Linux;我可能会在那里得到更多帮助。