传递继承自 ctypes.Structure 的 class 的子 class

Passing a subclass of a class that inherits from ctypes.Structure

为了代码整洁,我想让我的 c 结构自动生成的 ctypes 包装器与我的 Python-only 扩展(它有额外的辅助函数等)分开。

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

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

int CFunc(const CStruct **pCStruct);

自动生成的 python 绑定:

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

pyfunc = dll.CFunc
pyfunc.argtypes = (ctypes.POINTER(ctypes.POINTER(PyStruct)),)
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.
# 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" 的情况下做到这一点?

根据评论中的要求,这是一个使用 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))