met*_*ete 6 python struct ctypes pointers
我正在尝试在Linux中为本机库编写包装器.问题是这样的:
c中的定义:
int mymethod(mystruct* ptr)
在python中:
_lib.mymethod.argtypes = (ctypes.POINTER(mystruct),)
_lib.mymethod.restype = ctypes.c_int
s = mystruct()
_lib.mymethod(ctypes.byref(s))
引发:预期的LP_mystruct实例而不是指向mystruct的指针
_lib.mymethod(ctypes.pointer(s))
引发预期的LP_mystruct实例而不是LP_mystruct
错误.如何将结构作为指向本机方法的指针传递?
谢谢.
丈量
问题是来自ctypes的更高级别的"POINTER"在Python中是一个不同的对象,而不是返回的"通用指针"(ctypes.CArgObjectby ctypes.byref)或表示内存地址的单个数字(这是ctype返回的adrresof) -您可以注释您的功能以接收`ctypes.c_voidp并调用它_lib.mymethod(ctypes.addressof(a))-
或者如果你想在强制类型的一方工作以避免会导致Python崩溃的错误(类型错误会引发Python异常 - 传递给C语言的错误参数会导致Python解释器本身出现分段错误),你必须创建一个变量来保存新的"类型",它是您的结构的指针 - 然后使用您的结构地址创建此类型的实例:
mystruct_pointer = ctypes.POINTER(mystruct)
_lib.mymethod.argtypes = (mystruct_pointer,)
_lib.mymethod.restype = ctypes.c_int
s = mystruct()
_lib.mymethod(mystruct_pointer.from_address(ctypes.addressof(s)))
Run Code Online (Sandbox Code Playgroud)
(我知道这是一个老问题,但我认为接受的答案是一种不必要的解决方法,所以我想把它留在这里以供后代使用。)
实际上 ctypes 应该明确支持usingbyref()传递这样的指针:
ctypes 导出
byref()用于通过引用传递参数的函数。使用该pointer()函数可以实现相同的效果,但pointer()由于它构造了一个真正的指针对象,因此做了更多的工作,因此byref()如果您不需要 Python 本身的指针对象,则使用它会更快。
造成这种情况的可能原因是您在多个地方(例如,在不同的模块中)定义了结构 - 如果argtypes赋值看到一个定义而函数调用看到另一个定义,则会出现这种令人困惑的错误。换句话说,ctypes 尝试匹配mystruct内容(可能)相同的两种类型,并且具有完全相同的名称,但它们不是相同的类型。只要基本结构类型是单一类型对象,使用或- ctypes构造指向它的指针都没有关系pointer(),ctypes 将检测到基础(指向)类型是否相同。byref()POINTER()()
要验证是否是这种情况,请assert(_lib.mymethod.argtypes[0]._type_ == type(s))在调用外部函数之前尝试。
| 归档时间: |
|
| 查看次数: |
6146 次 |
| 最近记录: |