如何获得与python ctypes一起用作回调的方法? [英] How can I get methods to work as callbacks with python ctypes?

查看:188
本文介绍了如何获得与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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆