使用与系统不同版本的zlib.so进行Python cdll导入
大家好,
我正在尝试修改 zlib 并测试一些行为,所以我写了 mylib.c
和 mylib.h
。这两个文件是用来包装 zlib 函数的,像 InflateInit2()
这样的函数可以在里面调用。我用以下命令来编译和链接:
gcc -g -Wall -Werror -c -std=c99 -I./zlib-1.2.5 -I./ -fPIC mylib.c
gcc -shared mylib.o -o mylib.so
然后我用下面的方式把它导入到 Python 中:
mylib = cdll.LoadLibrary(os.getcwd() + '/mylib.so')
我需要一个不同于我系统上安装的 zlib 版本,所以我从源代码下载并编译了一个不同的版本(因为在系统上安装的那个版本不稳定)。现在我遇到的问题是,我在自定义编译的 zlib 源文件中所做的更改,在使用 mylib 的 Python 中并没有反映出来。Python(或者可能是我编译 mylib.so
的方法)似乎在使用系统上那个版本的 zlib。有没有办法指定“正确”的 zlib.so 版本呢?
1 个回答
1
我认为Python的源代码是静态链接了一个打包好的zlib库。如果你想让Python使用你自己的版本,可能需要下载Python的源代码,然后构建一个自定义的解释器,把你修改过的zlib库替换进去。
# system python static lib bundles the zlibmodule.o code
ares% nm -ao /usr/lib/libpython2.6.a|grep initzlib
/usr/lib/libpython2.6.a:zlibmodule.o:0000000000000000 T initzlib
更新:谢谢你提供的额外信息,我明白你想做什么了。
把你自定义的zlib放在一个共享对象里是行不通的,正如你发现的那样。你需要直接通过cdll.LoadLibrary()
返回的共享对象句柄来调用你自定义的zlib函数。你还需要通过扩展ctypes.Structure
来模拟一个z_stream
结构。
下面是一个部分示例,应该能帮助你入门:
from ctypes import *
class z_stream(Structure):
_fields_ = [
('next_in', c_char_p),
('avail_in', c_uint),
('total_in', c_ulong),
# finish adding all fields in the z_stream struct..
]
stream = z_stream()
zlib = cdll.LoadLibrary('./zlib-1.2.5/libz.so.1')
ret = zlib.deflateInit_(stream, 1, "1.2.5", sizeof(stream))
print ret