Python包装到C回调

Python包装到C回调,第1张

概述尝试创建一个需要在调用C回调时调用的 python回调 来自 Windows环境中的DLL.请查看以下代码以了解该问题. from ctypes import *#---------qsort Callback-------------#IntArray5 = c_int * 5ia = IntArray5(5,1,7,33,99)libc = cdll.msvcrtqsort = l 尝试创建一个需要在调用C回调时调用的 python回调
来自 Windows环境中的DLL.请查看以下代码以了解该问题.

from ctypes import *#---------qsort Callback-------------#IntArray5 = c_int * 5ia = IntArray5(5,1,7,33,99)libc = cdll.msvcrtqsort = libc.qsortqsort.restype = NoneCMPFUNC = CFUNCTYPE(c_int,POINTER(c_int),POINTER(c_int) )test = 0def py_cmp_func(a,b):    #print 'py_cmp_func:',a[0],b[0]    global test    test = 10000    return a[0]-b[0]cmp_func = CMPFUNC(py_cmp_func)qsort(ia,len(ia),sizeof(c_int),cmp_func)print "global test=",testfor item in ia : print item#----------Load DLL & Connect ------------#gobIDLL = WinDLL("C:\LMS\QCWWAN2k.dll")print  'Output of connect : ',gobIDLL.QCWWANConnect()#----------SetBytetotalsCallback----------#tx = POINTER(c_ulonglong)rx = POINTER(c_ulonglong)proto_callback = WINFUNCTYPE(c_voID_p,tx,rx)gtx = grx = 0 # Used to copy the response in the py_callbackdef py_callback(t,r):    sleep(10)    print 'python callback ...'    print "tx=",t,"rx=",r    global gtx,grx    gtx = 5000 # gtx = t    grx = 2000 # grx = r    #return 0callback = proto_callback(py_callback)gobIDLL.SetBytetotalsCallback.restype = c_ulonggobIDLL.SetBytetotalsCallback.argtypes = [proto_callback,c_byte]                    print "SetBytetotalsCallback = ",gobIDLL.SetBytetotalsCallback(callback,c_byte(256))print "gtx = ",gtxprint "grx = ",grx

DLL记录Prototype和SetBytetotalsCallback()方法的回调,如下所示.

原型:

ulONG QCWWANAPI2K SetSessionStateCallback( tFNSessionState pCallback );

打回来 :

voID BytetotalsCallback( ulONGLONG  txTotalBytes,ulONGLONG rxTotalBytes );

输出:

>>> global test= 100001573399Output of connect :  0SetBytetotalsCallback =  0gtx =  0grx =  0>>>>

目前的问题是整个程序被正确调用,
但是根本没有调用python回调.该程序从0状态退出
gobIDLL.SetBytetotalsCallback(callback,c_byte(256))方法,但写的callback()方法
在python中,在调用期间没有调用.

你能指出什么可以帮助进入python回调?
另一个示例qsort()方法奇妙地将指针传递给python函数指针.
无法在这里找到问题的根本原因.

TIA,

安东尼

解决方法 你不能. C/C++函数无法直接访问Python函数 – 函数原型可能需要指向C的指针.Python将向其传递指向其特定函数的内部数据结构的指针.

这是构建python的C扩展以包装该DLL并将其暴露给Python的时候.你要做的就是用C回调调用Python回调,因为可以做到.更清楚的是,您想要实现的目标是:

| This sIDe is C land i.e. "real" addresses                |Python objects --> C extension -- register callback with --> DLL                |                                             | in the python  |                                     Calls callback                |                                             |  interpreter <-------------- Callback in C extension  <-------                |

以下是从C构建调用python函数的一个非常快速的解释.您需要使用用于构建Python发行版的MSVC(或替代工具)来构建此代码;使用depends.exe找出它链接的msvcXX.dll.

全局状态通常被认为是坏的,但为了简单起见,我使用的是:

static PyObject* pyfunc_event_handler = NulL;static PyObject* pyfunc_event_args = NulL;

然后我添加了一个set handler函数,以便更容易地设置回调.但是,您不需要这样做,您只需要

static PyObject* set_event_handler(PyObject *self,PyObject *args){    PyObject *result = NulL;    PyObject *temp;

下一行是重要的一行 – 我允许传递两个python对象(PyArg_ParseTuple的O参数.一个对象包含函数,另一个包含其参数.

if (PyArg_ParseTuple(args,"OO",&temp,&pyfunc_event_args)) {        if (!PyCallable_Check(temp)) {            PyErr_SetString(PyExc_TypeError,"parameter must be a function");            return NulL;        }

整理参考. Python需要你这样做.

Py_XINCREF(temp);                    /* Add a reference to new func */        Py_XDECREF(pyfunc_event_handler);    /* dispose of prevIoUs callback */        pyfunc_event_handler = temp;         /* Remember new callback */        /* Boilerplate to return "None" */        Py_INCREF(Py_None);        result = Py_None;    }    return result;}

然后你可以在其他地方调用它:

PyObject* argList = Py_BuildValue("(O)",pyfunc_event_args); pyobjresult = PyObject_CallObject(pyfunc_event_handler,argList); Py_DECREF(argList);

不要忘记DECREF,你需要Python来gc argList.

从python中,使用它就像这样简单:

set_event_handler(func,some_tuple)

其中func具有匹配的参数,如下所示:

def func(obj):    /* handle obj */

您可能想要阅读的内容:

> LoadLibrary(从C加载DLL).
> GetProcAddress(找一个要打电话的功能).
> Extending Python with C or C++来自Python文档.

总结

以上是内存溢出为你收集整理的Python包装到C回调全部内容,希望文章能够帮你解决Python包装到C回调所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1192550.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-03
下一篇 2022-06-03

发表评论

登录后才能评论

评论列表(0条)

保存