问候,
我正在尝试修改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
然后我使用:
将其导入pythonmylib = cdll.LoadLibrary(os.getcwd() + '/mylib.so')
我需要一个zlib版本而不是我系统上安装的版本,所以我从源代码下载并编译了一个版本(在我的系统上安装它使它不稳定)。我现在面临的问题是,在python中使用mylib时,不会反映自定义编译的zlib源文件中的更改。 Python(或者我的编译方法mylib.so
)必须使用系统的zlib版本。有没有办法指定zlib.so的“正确”版本。
答案 0 :(得分: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函数。您需要通过扩展z_stream
来模拟ctypes.Structure
结构。
应该让你前进的部分例子:
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