question on callback functions with ctypes I try to use GoVCL( https://github.com/ying32/govcl ) in python via ctypes. GoVCL supplies C header and simple C demo under https://github.com/ying32/govcl/tree/master/Tools/makeCHeader/test
Now the simple python code can run on both win7 and win10 according to Eryk Sun's suggestion - thank you Eryk Sun. But I am still puzzled by 2 questions 1. the callback function does not been invoked, so there must be something wrong when I deal with it. However, I can't figure it out. 2. in the original main.c, there is no need to call `vcl.SetEventCallback(doEventCallbackProc)`. But I learn this in a python code that uses cffi to call GoVCL. How can I make the python code as simple as the C code? Thanks The following python code is a simplified version of the C code ```python import sys, os import ctypes # In Python 3.8+, ctypes no longer searches PATH or the # current working directory when loading DLLs. liblcl_path = os.path.join(os.path.split(os.path.realpath(__file__))[0], 'liblcl.dll') vcl = ctypes.CDLL(liblcl_path) def _doEventCallbackProc(f, args, argcount): print(f, args, argcount) if f == ctypes.addressof(onButton1Click): vcl.DShowMessage("Hello world!".encode('utf8')) elif f == ctypes.addressof(onFormKeyDown): fnOnFormKeyDown(f, args, argcount) elif f == ctypes.addressof(onFormKeyDown): fnOnFormKeyDown(f, args, argcount) doEventCallbackProc = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_long)(_doEventCallbackProc) def _onButton1Click(sender): vcl.ShowMessage("Hello world!"); onButton1Click = ctypes.CFUNCTYPE(None, ctypes.c_void_p)(_onButton1Click) print(ctypes.addressof(onButton1Click)) Char = ctypes.c_uint16 TShiftState = ctypes.c_uint32 def _onFormKeyDown(sender, key, shift): print(key, shift); onFormKeyDown = ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.POINTER(Char), TShiftState)(_onFormKeyDown) print(ctypes.addressof(onFormKeyDown)) def _onEditChange(sender): print("%s\n", vcl.Edit_GetText(sender)); onEditChange = ctypes.CFUNCTYPE(None, ctypes.c_void_p)(_onEditChange) print(ctypes.addressof(onEditChange)) def main(): vcl.SetEventCallback(doEventCallbackProc) vcl.Application_Instance.restype = ctypes.c_void_p Application = vcl.Application_Instance() vcl.Application_Initialize.argtypes = ctypes.c_void_p, vcl.Application_Initialize(Application) vcl.Application_CreateForm.argtypes = ctypes.c_void_p, ctypes.c_bool vcl.Application_CreateForm.restype = ctypes.c_void_p form = vcl.Application_CreateForm(Application, False); vcl.Form_SetCaption.argtypes = ctypes.c_void_p, ctypes.c_char_p vcl.Form_SetCaption(form, "LCL Form".encode('utf8')); vcl.Form_SetKeyPreview.argtypes = ctypes.c_void_p, ctypes.c_bool vcl.Form_SetKeyPreview(form, True); vcl.Form_SetOnKeyDown.argtypes = ctypes.c_void_p, ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.POINTER(Char), TShiftState) vcl.Form_SetOnKeyDown(form, onFormKeyDown); vcl.Button_Create.argtypes = ctypes.c_void_p, vcl.Button_Create.restype = ctypes.c_void_p btn = vcl.Button_Create(form); vcl.Button_SetParent.argtypes = ctypes.c_void_p, ctypes.c_void_p vcl.Button_SetParent(btn, form); vcl.Button_SetOnClick.argtypes = ctypes.c_void_p, ctypes.CFUNCTYPE(None, ctypes.c_void_p) vcl.Button_SetOnClick(btn, onButton1Click); vcl.Button_SetCaption.argtypes = ctypes.c_void_p, ctypes.c_char_p vcl.Button_SetCaption(btn, "button1".encode('utf8')); vcl.Button_SetLeft.argtypes = ctypes.c_void_p, ctypes.c_uint32 vcl.Button_SetLeft(btn, 100); vcl.Button_SetTop.argtypes = ctypes.c_void_p, ctypes.c_uint32 vcl.Button_SetTop(btn, 100); vcl.Edit_Create.argtypes = ctypes.c_void_p, vcl.Edit_Create.restype = ctypes.c_void_p edit = vcl.Edit_Create(form); vcl.Edit_SetParent.argtypes = ctypes.c_void_p, ctypes.c_void_p vcl.Edit_SetParent(edit, form); vcl.Edit_SetOnChange.argtypes = ctypes.c_void_p, ctypes.CFUNCTYPE(None, ctypes.c_void_p) vcl.Edit_SetOnChange(edit, onEditChange); vcl.Application_Run.argtypes = ctypes.c_void_p, vcl.Application_Run(Application); main() ``` the C code ```C #include "liblcl.h" #ifdef _WIN32 char *UTF8Decode(char* str) { int len = MultiByteToWideChar(CP_UTF8, 0, str, -1, 0, 0); wchar_t* wCharBuffer = (wchar_t*)malloc(len * sizeof(wchar_t) + 1); MultiByteToWideChar(CP_UTF8, 0, str, -1, wCharBuffer, len); len = WideCharToMultiByte(CP_ACP, 0, wCharBuffer, -1, 0, 0, 0, NULL); char* aCharBuffer = (char*)malloc(len * sizeof(char) + 1); WideCharToMultiByte(CP_ACP, 0, wCharBuffer, -1, aCharBuffer, len, 0, NULL); free((void*)wCharBuffer); return aCharBuffer; } #endif void onButton1Click(TObject sender) { ShowMessage("Hello world!"); } void onOnDropFiles(TObject sender, void* aFileNames, intptr_t len) { printf("aFileNames: %p, len=%d\n", aFileNames, len); intptr_t i; for (i = 0; i < len; i++) { #ifdef _WIN32 char *filename = UTF8Decode(GetStringArrOf(aFileNames, i)); #else char *filename = GetStringArrOf(aFileNames, i); #endif printf("file[%d]=%s\n", i+1, filename); #ifdef _WIN32 free((void*)filename); #endif } } void onFormKeyDown(TObject sender, Char* key, TShiftState shift) { printf("key=%d, shift=%d\n", *key, shift); if (*key == vkReturn) { ShowMessage("press Enter!"); } TShiftState s = Include(0, ssAlt); if (InSet(s, ssAlt)) { printf("ssAlt1\n"); } s = Exclude(s, ssAlt); if (!InSet(s, ssAlt)) { printf("ssAlt2\n"); } } void onEditChange(TObject sender) { printf("%s\n", Edit_GetText(sender)); } int main() { #ifdef _WIN32 if (load_liblcl("liblcl.dll")) { #endif #ifdef __linux__ if (load_liblcl("liblcl.so")) { #endif #ifdef __APPLE__ if (load_liblcl("liblcl.dylib")) { #endif Application_Initialize(Application); TForm form = Application_CreateForm(Application, FALSE); Form_SetCaption(form, "LCL Form"); Form_SetPosition(form, poScreenCenter); Form_SetAllowDropFiles(form, TRUE); Form_SetOnDropFiles(form, onOnDropFiles); Form_SetKeyPreview(form, TRUE); Form_SetOnKeyDown(form, onFormKeyDown); TButton btn = Button_Create(form); Button_SetParent(btn, form); Button_SetOnClick(btn, onButton1Click); Button_SetCaption(btn, "button1"); Button_SetLeft(btn, 100); Button_SetTop(btn, 100); TEdit edit = Edit_Create(form); Edit_SetParent(edit, form); Edit_SetLeft(edit, 10); Edit_SetTop(edit, 10); Edit_SetOnChange(edit, onEditChange); Application_Run(Application); close_liblcl(); } return 0; } ``` -- https://mail.python.org/mailman/listinfo/python-list