我有一个闭源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
答案 0 :(得分:0)
我让它适用于一个基本案例,但似乎你在同一时间发现了相同的解决方案,但它并没有为你工作。我会描述我做了什么。
首先,创建一个包含一些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
选项。