从python访问没有-fPIC编译的库

时间:2014-10-23 02:14:40

标签: python linux shared-libraries ctypes fpic

我有一个闭源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

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选项。