2

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

1 回答 1

0

我使它适用于基本案例,但似乎您几乎在同一时间发现了相同的解决方案,但它对您不起作用。无论如何,我将描述我做了什么。

首先,创建一个static.c包含一些 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:

从这里开始:将共享库与静态库链接:静态库的编译方式必须与应用程序链接它的方式不同吗?-mimpure-text从非 PIC 静态库创建共享库时,您似乎需要添加该选项。

于 2014-10-23T07:08:19.817 回答