gpt4 book ai didi

python - 我怎样才能得到方法作为 python ctypes 的回调?

转载 作者:太空狗 更新时间:2023-10-29 17:47:26 27 4
gpt4 key购买 nike

我有一个与 python ctypes 包交互的 C api。一切正常,除了这个小花絮。

为了将函数注册为某些通知的回调,我调用了这个函数:

void RegisterNotifyCallback( int loginId, int extraFlags, void *(*callbackFunc)(Notification *))

所以在 python 中我的代码看起来像:

CALLBACK = ctypes.CFUNCTYPE(None, ctypes.POINTER(Notification))
func = CALLBACK(myPythonCallback)
myLib.RegisterNofityCallback(45454, 0, func)

如果 myPythonCallback 的值是 FunctionType(即不是方法),它可以正常工作并使用正确的参数调用回调函数。如果它是一个 MethodType,它仍然会调用该方法,但一旦该方法完成就会出现段错误。

编辑

澄清一下,当我说函数类型时,我的意思是 myPythonCallback 被定义为一个函数,

def myPythonCallback(Notification):
...do something with the Notification object i get passed in

当我说它是 MethodType 时,我指的是类方法:

class MyClass(object):
def myPythonCallback(self, Notification):
...do something with Notification

它在第二种类型上爆炸了。

有什么简单的解决方法吗?或者有人可以向我解释为什么会这样吗?

非常感谢,铝。

编辑

进一步挖掘 GDB 得到了这个:

Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 1544567712 (LWP 5389)] 0x555ae962 in instancemethod_dealloc (im=0x558ed644) at Objects/classobject.c:2360 2360    Objects/classobject.c: No such file or directory.
in Objects/classobject.c (gdb) backtrace
#0 0x555ae962 in instancemethod_dealloc (im=0x558ed644) at Objects/classobject.c:2360
#1 0x555f6a61 in tupledealloc (op=0x5592010c) at Objects/tupleobject.c:220
#2 0x555aeed1 in instancemethod_call (func=0x558db8ec, arg=0x5592010c, kw=0x0) at Objects/classobject.c:2579
#3 0x5559aedb in PyObject_Call (func=0x558db8ec, arg=0x5592c0ec, kw=0x0) at Objects/abstract.c:2529
#4 0x5563d5af in PyEval_CallObjectWithKeywords (func=0x558db8ec, arg=0x5592c0ec, kw=0x0) at Python/ceval.c:3881
#5 0x5559ae6a in PyObject_CallObject (o=0x0, a=0x0) at Objects/abstract.c:2517

传入 instancemethod_dealloc 的值是:

(gdb) x 0x558ed644 0x558ed644:     0x00000000

您认为这是可以解决的吗?

最佳答案

据我所知,您不能调用绑定(bind)方法,因为它缺少 self 参数。我使用闭包解决了这个问题,如下所示:

CALLBACK = ctypes.CFUNCTYPE(None, ctypes.POINTER(Notification))

class MyClass(object):

def getCallbackFunc(self):
def func(Notification):
self.doSomething(Notification)
return CALLBACK(func)

def doRegister(self):
myLib.RegisterNofityCallback(45454, 0, self.getCallbackFunc())

关于python - 我怎样才能得到方法作为 python ctypes 的回调?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7259794/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com