Jul-11-2020, 09:02 AM
Hi, I met a case in which NULL can be used as a C function's parameter which is actually a pointer function. I can't finger out how to do it, can anyone help. Thanks
1. the case
The C function in [LCUI](https://github.com/lc-soft/LCUI) is defined as
2. the 1st attempt
1. the case
The C function in [LCUI](https://github.com/lc-soft/LCUI) is defined as
typedef void(*LCUI_WidgetEventFunc)(LCUI_Widget, LCUI_WidgetEvent, void*);
LCUI_API int Widget_BindEvent(LCUI_Widget widget, const char *event_name,
LCUI_WidgetEventFunc func, void *data,
void(*destroy_data)(void*));which is called in [helloworld](https://github.com/lc-soft/LCUI/blob/dev...orld.c#L31) asstatic void OnBtnClick(LCUI_Widget self, LCUI_WidgetEvent e, void *arg){
do something();
}
Widget_BindEvent(btn, "click", OnBtnClick, NULL, NULL);Then I try to translate it into python2. the 1st attempt
LCUI_WidgetEventFunc = ctypes.CFUNCTYPE(None, LCUI_Widget, LCUI_WidgetEvent, ctypes.c_void_p)
_Widget_BindEvent = dll.Widget_BindEvent
#~ _Widget_BindEvent.argtypes = LCUI_Widget, ctypes.c_char_p, LCUI_WidgetEventFunc, ctypes.c_void_p, ctypes.c_void_p
def Widget_BindEvent( widget, event_name, func, data, destroy_data,):
event_name = event_name.encode('utf8')
func = LCUI_WidgetEventFunc(func)
return _Widget_BindEvent( widget, event_name, func, data, destroy_data)then I call it as def OnBtnClick(self, e, arg):
do something()
Widget_BindEvent( btn, "click", LCUI_WidgetEventFunc(OnBtnClick),
None,
ctypes.cast(None, ctypes.CFUNCTYPE(None, ctypes.c_void_p))
);But python fails to run this code and saysOutput:Traceback (most recent call last):
File "helloworld.py", line 60, in <module>
main()
File "helloworld.py", line 54, in main
ctypes.cast(None, ctypes.CFUNCTYPE(None, ctypes.c_void_p))
File "r:\lc\LCUI.py", line 88, in Widget_BindEvent
destroy_data
OSError: exception: access violation reading 0x00000000000002703. the 2nd try_Widget_BindEvent = dll.Widget_BindEvent
prototype = ctypes.CFUNCTYPE(ctypes.c_int,
LCUI_Widget,
ctypes.c_char_p,
LCUI_WidgetEventFunc,
ctypes.c_void_p,
ctypes.CFUNCTYPE(None, ctypes.c_void_p)
)
Widget_BindEvent = prototype(_Widget_BindEvent)
Widget_BindEvent( btn,
"click".encode(),
LCUI_WidgetEventFunc(OnBtnClick),
None,
ctypes.cast(None, ctypes.CFUNCTYPE(None, ctypes.c_void_p))
);this time python runs the code but saysOutput:Traceback (most recent call last):
File "_ctypes/callbacks.c", line 234, in 'calling callback function'
OSError: exception: access violation reading 0x0000000000000270So what is the proper way to wrap Widget_BindEvent so that we can use real function or NULL in it?
