在结构上将Python的回调传递给C.

时间:2017-07-14 15:50:20

标签: python c

我一直试图将回调函数从Python传递给结构包含的C。到目前为止,我还没有对如何将Python函数传递回C感到好运。

C struct定义如下:

typedef int (* TOUCH_CALLBACK_FUNC)(int x, int y);
typedef int (* HARDKEY_CALLBACK_FUNC)(int key);

typedef struct _rect
{
    u32 left;
    u32 top;
    u32 width;
    u32 height;  
} RECT;

typedef struct _touch_data
{
    u8  sign[16];
    u8  *file;
    RECT rect;
    u32 destWidth;
    u32 destHeight;
    u32 uiTimeOut;
    TOUCH_CALLBACK_FUNC cb;
    HARDKEY_CALLBACK_FUNC keyCb;
    void *extArg;
    void *extArg2;
} TOUCH_DATA;

Python定义如下

from ctypes import Structure, CFUNCTYPE, c_int32, POINTER

TOUCH_CALLBACK_FUNC = CFUNCTYPE(c_int32, POINTER(c_int32), POINTER(c_int32))
HARDKEY_CALLBACK_FUNC = CFUNCTYPE(c_int32, POINTER(c_int32))

class Rect(Structure):
    _pack_ = 1
    _fields_ = [('left', c_int32),
                  ('top', c_int32),
                  ('width', c_int32),
                  ('height', c_int32)]

class TouchDataStruct(Structure):
    _pack_ = 1
    _fields_ = [('sign', c_char * 16),
                  ('file', c_char_p),
                  ('rect', Rect),
                  ('destWidth', c_uint32),
                  ('destHeight', c_uint32),
                  ('touchCallback', TOUCH_CALLBACK_FUNC),
                  ('keyCallback', HARDKEY_CALLBACK_FUNC),
                  ('uiTimeOut', c_uint32),
                  ('extArg', c_void_p),
                  ('extArg2', c_void_p)]

我从Python执行以下代码:

def touch_cb(x, y):
    return 0


def key_cb(key):
    return 0

data = TouchDataStruct(
    file='...'.encode('ascii'),
    rect=Rect(left=0,top=0,width=50,height=25),
    cb=TOUCH_CALLBACK_FUNC(touch_cb),
    keyCb=TOUCH_CALLBACK_FUNC(key_cb),
    destWidth=75,
    destHeight=30,
    uiTimeOut=60000
)

cwrapper.process(data)

实际错误是C接收的结构的size_t为48,而实际C结构的size_t为64。

要使用以下代码段接收C I' m上的结构:

PyObject *Wrapper_Process(PyObject *self, PyObject *args) {
    TOUCH_DATA *touch_data;
    size_t size;

    PyArg_ParseTuple(args, "y#", &touch_data, &size);
    if (size != sizeof(TOUCH_DATA)) {
        // Raise error here!
    }
}

提前谢谢你:)

编辑1:在两个结构中添加了更多详细信息并详细说明了错误

编辑2:忘记将字符串转换为字节

编辑3:示例代码对字段和包有双重下划线(在实际代码中是正确的,只需在此处进行更正)

0 个答案:

没有答案