python 调用 cgo 库 -- 32 位和 64 位问题
python calling cgo library -- 32 bit and 64 bit issue
我构建了一个cgo库并使用python(带有ctypes包)来调用它。代码被编译成 32 位和 64 位版本,这些库分别被 32 位和 64 位 python 程序调用。我发现显然参数没有正确传递。我认为这可能与 python 程序和库之间数组的定义和传递方式有关。
例如go库“callnames.so”中的一个函数定义为
func Initialize(namelist []*C.char, grp *C.char)
调用此函数的 python 代码部分是
class GoSliceChar(结构):
字段 = [("数据", POINTER(c_char_p)), ("len", c_longlong), ("cap", c_longlong )]
numNames = 3
n1 = c_char_p(b"peter")
n2 = c_char_p(b"tom")
n3 = c_char_p(b"nancy")
group = c_char_p(b"group1")
names = GoSliceChar((c_char_p * numComponents)(n1, n2, n3), numNames, numNames )
lib = cdll.LoadLibrary("./callnames.so")
lib.Initialize(names, group)
这些代码在64位环境下工作得很好,即python-64 + 64位cgo库。但是,当我切换到 32 位时,问题出现了。我通过将 python 中 GoSliceChar 的定义更改为
进行了快速而肮脏的修复
class GoSliceChar(Structure):
_fields_ = [("data", POINTER(c_char_p)), ("len", c_long), ("cap", c_long)]
但是我不是很明白为什么问题解决了,是否是一个固解。请帮忙。谢谢
我对我的问题有了一些新发现。看起来在编译 cgo 库之后,会自动生成一个 .h 文件。在此文件中,所有数组都定义为 GoSlice
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
对于 32 位库,GoInt 由
定义
typedef GoInt32 GoInt;
而对于 64 位库,GoInt 由
定义
typedef GoInt32 GoInt;
在我看来,必须确保 python 代码在调用这些库时适应这一点
class GoSliceChar(Structure):
if is_64bit():
_fields_ = [("data", POINTER(c_char_p)), ("len", c_longlong), ("cap", c_longlong)]
else:
_fields_ = [("data", POINTER(c_char_p)), ("len", c_long), ("cap", c_long)]
我构建了一个cgo库并使用python(带有ctypes包)来调用它。代码被编译成 32 位和 64 位版本,这些库分别被 32 位和 64 位 python 程序调用。我发现显然参数没有正确传递。我认为这可能与 python 程序和库之间数组的定义和传递方式有关。
例如go库“callnames.so”中的一个函数定义为
func Initialize(namelist []*C.char, grp *C.char)
调用此函数的 python 代码部分是 class GoSliceChar(结构): 字段 = [("数据", POINTER(c_char_p)), ("len", c_longlong), ("cap", c_longlong )]
numNames = 3
n1 = c_char_p(b"peter")
n2 = c_char_p(b"tom")
n3 = c_char_p(b"nancy")
group = c_char_p(b"group1")
names = GoSliceChar((c_char_p * numComponents)(n1, n2, n3), numNames, numNames )
lib = cdll.LoadLibrary("./callnames.so")
lib.Initialize(names, group)
这些代码在64位环境下工作得很好,即python-64 + 64位cgo库。但是,当我切换到 32 位时,问题出现了。我通过将 python 中 GoSliceChar 的定义更改为
进行了快速而肮脏的修复 class GoSliceChar(Structure):
_fields_ = [("data", POINTER(c_char_p)), ("len", c_long), ("cap", c_long)]
但是我不是很明白为什么问题解决了,是否是一个固解。请帮忙。谢谢
我对我的问题有了一些新发现。看起来在编译 cgo 库之后,会自动生成一个 .h 文件。在此文件中,所有数组都定义为 GoSlice
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
对于 32 位库,GoInt 由
定义typedef GoInt32 GoInt;
而对于 64 位库,GoInt 由
定义 typedef GoInt32 GoInt;
在我看来,必须确保 python 代码在调用这些库时适应这一点
class GoSliceChar(Structure):
if is_64bit():
_fields_ = [("data", POINTER(c_char_p)), ("len", c_longlong), ("cap", c_longlong)]
else:
_fields_ = [("data", POINTER(c_char_p)), ("len", c_long), ("cap", c_long)]