【发布时间】:2021-09-13 07:18:52
【问题描述】:
我有一个没有源代码的静态库,需要从 LuaJIT FFI 动态调用它的符号。
由于它是静态的,我无法动态加载它,所以我尝试将它嵌入到共享库中,然后在运行时加载共享库。
问题是静态库的导出符号存在于共享库的符号表中,但未定义。
nm libUSBDevices.a
显示了很多行,其中我感兴趣的符号:
00001d80 T _ZN9USBDevice16FlightControllerC1EPKc
00001e30 T _ZN9USBDevice16FlightControllerD1Ev
00000140 T _ZN9USBDevice7AxisFctC1Ev
00000180 T _ZN9USBDevice7AxisFctclEv
然后我使用这两个 g++ 命令编译了共享库:
g++ -m32 -c -Wall -Werror -fpic USBDevicesLoader.cpp -llibUSBDevices.a
输出 USBDevicesLoader.o(USBDevicesLoader.cpp 包含一些导出函数,这些函数调用静态库中的符号,这些函数正确存在于 .so 中)
g++ -m32 -shared -o libUSBDevicesLoader.so USBDevicesLoader.o
这会输出共享库,但在运行时加载时会显示:
[...] symbol lookup error: /home/me/USBDevices-loader/libUSBDevicesLoader.so: undefined symbol: _ZN9USBDevice16FlightControllerC1EPKc
当我在共享库上运行 nm 时,它会将符号显示为未定义:
U _ZN9USBDevice16FlightControllerC1EPKc
U _ZN9USBDevice7AxisFctclEv
我认为问题出在编译命令的某个地方,我还尝试直接从 .a 构建共享库,而无需先编译 cpp(只需将第二个命令中的 USBDevicesLoader.o 替换为 .a,跳过第一个命令),但问题仍然存在。
那么,有没有办法将静态库的所有符号(没有源代码)嵌入到动态库中,然后可以在运行时加载和使用?谢谢
【问题讨论】:
-
@RichardCritten 感谢您的回答。不幸的是,这并没有改变任何东西,.so 中的符号仍然是未定义的,并且加载仍然报告“未定义的符号”。此外,如果我理解正确,整个存档选项似乎告诉链接器包含所有目标文件,而不是仅包含由共享库函数实际调用的目标文件。但毕竟我的共享库中的所有函数都使用了我试图嵌入的符号,所以我想这应该不是问题。
-
@endyx 你也可以尝试在构建共享库
g++ -m32 -shared -o libUSBDevicesLoader.so USBDevicesLoader.o libUSBDevices.a时添加静态库。希望它有效 -
如果你使用 nm ... | c++filt 它可能会让您更好地了解缺少的内容。至少你可以看到解构后的名称是什么。
-
@nhatnq 谢谢,它似乎工作得更好,很多名称使用 nm 时不会显示为“U”。然而,其他一些符号现在是未定义的,但我认为我正在让它工作。我无法猜测为什么添加 libUSBDevices.a 可以使它工作,而当我删除 USBDevicesLoader.o 时它不会(将 .so 直接从 .a 中取出)