如何获得与python ctypes一起用作回调的方法? [英] How can I get methods to work as callbacks with python ctypes?
问题描述
我有一个C api与python ctypes软件包连接。
I have an C api that i'm interfacing with the python ctypes package. Everything works well, except this little tidbit.
要将功能注册为某些通知的回调,我称这个功能为:
To register functions as callbacks to some notifications, i call this function :
void RegisterNotifyCallback( int loginId, int extraFlags, void *(*callbackFunc)(Notification *))
因此在python中,我的代码如下:
so in python my code looks like :
CALLBACK = ctypes.CFUNCTYPE(None, ctypes.POINTER(Notification))
func = CALLBACK(myPythonCallback)
myLib.RegisterNofityCallback(45454, 0, func)
如果myPythonCallback的值是FunctionType(即不是方法),则可以正常工作并使用正确的参数调用回调函数。如果它是MethodType,它仍然会调用该方法,但是一旦该方法完成,就会出现段错误。
If the value of myPythonCallback is a FunctionType (i.e. not a method), it works fine and calls the callback function with the correct parameters. If it's a MethodType, it still calls the method but then blows up with a segfault once the method is finished.
edit
为了澄清,当我说函数类型时,我的意思是myPythonCallback被定义为一个函数,
To clarify, when i say function type i mean that myPythonCallback is defined as a function,
def myPythonCallback(Notification):
...do something with the Notification object i get passed in
$ b中传递$ b
当我说它是一个MethodType时,我的意思是一个类方法:
When i say it's a MethodType, i mean a class method :
class MyClass(object):
def myPythonCallback(self, Notification):
...do something with Notification
这附近容易吗?或者有人可以向我解释为什么会发生这种情况?
Is there an easy away around this ? Or can someone offer me an explanation as to why this is happening ?
非常感谢,
Al。
Many thanks, Al.
edit
与GDB进一步挖掘可以使我做到这一点:
Digging a bit further with GDB gives me this :
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的值是:
and the value passed into instancemethod_dealloc is :
(gdb) x 0x558ed644 0x558ed644: 0x00000000
您认为这是可以解决的吗?
Do you reckon this is fixable ?
推荐答案
据我所知,您不能调用绑定方法,因为它缺少sel f参数。我使用闭包来解决此问题,如下所示:
You can't, so far as I know, call a bound method because it is missing the self parameter. I solve this problem using a closure, like this:
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 ctypes一起用作回调的方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!