为了账号安全,请及时绑定邮箱和手机立即绑定

python 调用 cgo 库 -- 32 位和 64 位问题

python 调用 cgo 库 -- 32 位和 64 位问题

Go
鸿蒙传说 2022-08-09 20:31:19
我构建了一个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)]


查看完整回答
反对 回复 2022-08-09
  • 1 回答
  • 0 关注
  • 238 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号