我构建了一个cgo库,并使用python(带有ctypes包)来调用它。代码被编译成32位和64位版本,这些库分别由32位和64位python程序调用。我发现显然参数没有正确传递。我认为这可能与数组在python程序和库之间的定义和传递方式有关。例如,go 库“callnames.so”中的函数定义为func Initialize(namelist []*C.char, grp *C.char)调用此函数的python代码部分是类GoSliceChar(Structure):字段= [(“data”, POINTER(c_char_p)), (“len”, c_longlong), (“cap”, c_longlong)]numNames = 3n1 = 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)] 但我真的不明白为什么这个问题得到了解决,以及它是否是一个可靠的解决方案。请帮忙。谢谢。
1 回答

宝慕林4294392
TA贡献2021条经验 获得超8个赞
我对我的问题有一些新的发现。看起来就像编译 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)]
- 1 回答
- 0 关注
- 238 浏览
添加回答
举报
0/150
提交
取消