在C中为函数指针回调函数编写Python ctypes
问题内容:
我正在尝试编写python代码来调用dll函数,并停留在下面的函数中,我认为这与typedef回调函数或函数指针有关。
我已经测试了以下代码,当调用回调函数时,python崩溃(窗口通知-python.exe停止响应)且没有调试消息。
我很困惑,任何帮助将不胜感激:)
谢谢!
C:
#ifdef O_Win32
/** @cond */
#ifdef P_EXPORTS
#define API __declspec(dllexport)
#else
#define API __declspec(dllimport)
#endif // #ifdef P_EXPORTS
/** @endcond */
#endif // #ifdef O_Win32
// Type definition
typedef void (__stdcall *StatusCB)(int nErrorCode, int nSID, void *pArg);
//Function
void GetStatus(StatusCB StatusFn, void *pArg);
蟒蛇:
from ctypes import *
def StatusCB(nErrorCode, nSID, pArg):
print 'Hello world'
def start():
lib = cdll.LoadLibrary('API.dll')
CMPFUNC = WINFUNCTYPE(c_int, c_int, c_void_p)
cmp_func = CMPFUNC(StatusCB)
status_func = lib.GetStatus
status_func(cmp_func)
问题答案:
您的回调类型签名错误;您忘记了结果类型。当函数退出时,它也会收集垃圾。您需要使其全球化。
您的GetStatus
电话缺少论据pArg
。另外,在使用指针时,您需要定义argtypes
,否则在64位平台上会遇到问题。ctypes的默认参数类型为C
int
。
from ctypes import *
api = CDLL('API.dll')
StatusCB = WINFUNCTYPE(None, c_int, c_int, c_void_p)
GetStatus = api.GetStatus
GetStatus.argtypes = [StatusCB, c_void_p]
GetStatus.restype = None
def status_fn(nErrorCode, nSID, pArg):
print 'Hello world'
print pArg[0] # 42?
# reference the callback to keep it alive
_status_fn = StatusCB(status_fn)
arg = c_int(42) # passed to callback?
def start():
GetStatus(_status_fn, byref(arg))