【发布时间】:2017-09-29 19:42:59
【问题描述】:
我有一个 c 中的 DLL,适用于 Windows 平台,其结构类似于以下内容:
C 结构
typedef struct some_struct {
int (_stdcall *function)(int arg1, int arg2);
...
}SOME_STRUCT;
我已经定义了一个 python ctypes 结构来模仿这个结构
Python 结构
class SOME_STRUCT(Structure):
_fields_ = [('function', POINTER(CFUNCTYPE(c_int, c_int, c_int))), ...]
这个结构在 C 代码中的要点是注册一个回调函数,该函数在其自己的线程中的某些触发器上执行。如果可能的话,我想要做的是将回调设置为 Python 函数,这样当 C 结构中的函数从 C 代码中调用时,执行的是 Python 函数。
我在 python 中尝试完成这个(不起作用)如下:
def func(arg1,arg2):
print('I was called!')
return 0
struct = SOME_STRUCT()
prototype = CFUNCTYPE(c_int, c_int, c_int)
struct.function = byref(prototype(func))
我得到的具体错误(这可能不是我唯一的问题)是它抱怨 struct.function 期待 LP_CFunctionType 实例但得到了 CArgObject 实例。我该怎么做?
【问题讨论】:
-
ctypes 文档docs.python.org/3/library/ctypes.html#callback-functions 中的示例没有像您那样使用对
byref的调用。如果您删除 byref 调用并只执行struct.function = prototype(func),它是否有效? -
@PaulCornelius 我试过这样做,但该函数似乎永远不会被调用。我从来没有看到它的输出。我试图按照您指出的示例进行操作,但我相信我需要
byref或类似的东西,因为我试图将指针分配给函数而不是函数本身(示例正在执行此操作)。 -
那样的话,我还有一个想法。如果 CFUNCTYPE 返回一个表示函数指针的对象,那么您可能不希望在结构定义中调用 POINTER() 函数。