传递继承自的类的子类ctypes.结构

2024-09-29 00:12:01 发布

您现在位置:Python中文网/ 问答频道 /正文

为了保持代码的整洁,我希望将c结构的自动生成ctypes包装器与Python扩展(它有附加的helper函数等)分开。在

我无法将子类结构传递给我自动生成的绑定。有办法吗?在

// C Code
typedef struct CStruct
{
    int value;
} CStruct;

int CFunc(const CStruct **pCStruct);

自动生成的python绑定:

^{pr2}$

从我的绑定创建一个子类,并尝试传递给我的func:

class PySubStruct(PyStruct):
    def __init__(self, *args, **kwargs):
        super(PySubStruct, self).__init__(*args, **kwargs)

    def value_mult(self, factor):
        return self.value * factor

# Works great
structptr = ctypes.pointer(PyStruct())
result_A = pyfunc(ctypes.byref(structptr))

# Create an instance of substruct and call the c-func.
# Raises exception
substructptr = ctypes.pointer(PySubStruct())
result_B = pyfunc(ctypes.byref(substructptr))

以下是例外:

ctypes.ArgumentError: argument 3: <type 'exceptions.TypeError'>:
    expected LP_LP_PyStruct instance instead of 
    pointer to LP_PySubStruct

有没有一种方法可以在不修改自动生成的绑定或“monkey patching”的情况下做到这一点?在


Tags: selfinitvaluedefargsctypes子类结构
1条回答
网友
1楼 · 发布于 2024-09-29 00:12:01

按照评论中的要求,下面是一个使用ctypes.cast的示例:

# Python Implementation
import ctypes
class PyStruct(ctypes.Structure):
    _fields_ = [('value', ctypes.c_int32)]

# Declaring a type name for simplicity
LP_LP_PyStruct = ctypes.POINTER(ctypes.POINTER(PyStruct))

pyfunc = ctypes.CDLL('x').CFunc
pyfunc.argtypes = (LP_LP_PyStruct,) # Using the typename
pyfunc.restype = ctypes.c_int32

class PySubStruct(PyStruct):
    def __init__(self, *args, **kwargs):
        super(PySubStruct, self).__init__(*args, **kwargs)

    def value_mult(self, factor):
        return self.value * factor

# Works great
structptr = ctypes.pointer(PyStruct())
result_A = pyfunc(ctypes.byref(structptr))

# Create an instance of substruct and call the c-func.
# Now works great
substructptr = ctypes.pointer(PySubStruct())
result_B = pyfunc(ctypes.cast(ctypes.byref(substructptr),LP_LP_PyStruct))

相关问题 更多 >