我有一个闭源 x86_64 库,我想从 Linux 上的 Python 访问它。
我通常为此使用 ctypes。
但是这个库是作为存档 (*.a) 文件提供的。我无法将库重新链接到动态 *.so 中,因为它是在没有 -fPIC 选项的情况下编译的。 ctypes 需要 *.so dll。
除了向这个库的打包者提示之外,我还能做些什么来把它变成一个*.so?也许以某种方式编写包装函数?
编辑:
尝试 https://stackoverflow.com/a/2657390/4323 中的答案:
gcc -shared -o closed_lib.so -Wl,--whole-archive -fPIC closed_lib.a -Wl,--no-whole-archive
/usr/bin/ld: closed_lib.a(myFFT.o): relocation R_X86_64_32S against `.bss' can not be used when making a shared object; recompile with -fPIC
closed_lib.a(myFFT.o): error adding symbols: Bad value
collect2: error: ld returned 1 exit status
make: *** [closed_lib.so] Error 1
最佳答案
我让它适用于一个基本案例,但您似乎几乎在同一时间发现了相同的解决方案,但它对您不起作用。我将描述我所做的一切。
首先,制作一个包含一些 C 代码的文件 static.c
(如果您已经构建了一个静态库,请跳过这个):
int foo(int x) {
return x * 2;
}
制作一个静态库:
gcc -g -o static.o -c static.c
ar -rv libstatic.a static.o
现在我们有了位置相关的静态库。让我们创建一个共享库吧!
gcc -g -shared -o libshared.so -Wl,--whole-archive -L. -lstatic -Wl,--no-whole-archive
最后,使用 Python 对其进行测试:
import ctypes
print ctypes.cdll.LoadLibrary('./libshared.so').foo(42)
这给出了预期的 84
。
我借用了另一个答案的方法,在这里:https://stackoverflow.com/a/10963770/4323
根据这个:https://stackoverflow.com/a/19768349/4323可能无法做您想做的事。也许你真的需要重建你的静态库。或者,如果您不需要那些特定符号,也许您可以编辑掉导致问题的符号?您有真正需要的符号列表吗?
如果以上方法均无济于事,另一种非常不同的方法是创建一个链接到您的静态库的可执行程序,并执行类似 RPC 的操作以将该进程中的代码作为服务运行。
旧答案,似乎只适用于 Solaris:
来自这里:Linking a shared library against a static library: must the static library be compiled differently than if an application were linking it?从非 PIC 静态库创建共享库时,您似乎需要添加 -mimpure-text
选项。
关于python - 从python访问没有-fPIC编译的库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26520241/