gpt4 book ai didi

python - 使用 cython 将回调函数从 python 传递到 c

转载 作者:行者123 更新时间:2023-11-28 21:58:38 24 4
gpt4 key购买 nike

首先我想说我没有修改甚至查看 c 源代码的选项,所以任何涉及修改 c 文件的东西都没有帮助。

在 VP.h 中:

typedef enum VPEvent { 
...
EVENT_OBJECT_CLICK,
...
}
...
typedef void *VPInstance;
typedef void(*VPEventHandler)(VPInstance);
...
VPSDK_API VPInstance vp_create(void);
...
VPSDK_API int vp_event_set(VPInstance instance, VPEvent eventname, VPEventHandler event);
...

在 VP.pyx 中:

cdef extern from "VP.h":
...
cdef enum VPEvent:
...
VP_EVENT_OBJECT_CLICK,
...

...
ctypedef void *VPInstance
ctypedef void(*VPEventHandler)(VPInstance)
...
VPInstance vp_create()
...
int vp_event_set(VPInstance instance, VPEvent eventname, VPEventHandler event)
...

...
EVENT_OBJECT_CLICK = VP_EVENT_OBJECT_CLICK
...

cdef class create:
cdef VPInstance instance

def __init__(self):
self.instance = vp_create()
...
def event_set(self, eventname, event):
return vp_event_set(self.instance, eventname, event)

我想在 Python 中拥有什么:

import VP
...
def click(bot):
bot.say("Someone clicked something!")
...
bot = VP.create()
bot.event_set(VP.EVENT_OBJECT_CLICK, click)

这就是你在 c 中的做法:

#include <VP.h>

void click(VPInstance instance) {
vp_say(instance, "Someone clicked something!");
}

int main(int argc, char ** argv) {
...
VPInstance instance;
instance = vp_create();
...
vp_event_set(instance, VP_EVENT_OBJECT_CLICK, click)
}

但是问题是在编译 VP.pyx 时我得到了

Cannot convert Python object to 'VPEventHandler'

同样,默认情况下回调被赋予一个 VPInstance 指针,但我想将这个值抽象到一个类中。

最佳答案

你可能已经猜到了,问题出在通话中

bot.event_set(VP.EVENT_OBJECT_CLICK, click)

实际上,第三个参数 click 是一个 Python 函数对象,您在 event_set 中将其传递给 vp_event_set .唉,vp_event_set 需要一个 VPEventHandler,它是 void(*VPEventHandler)(VPInstance); 类型的 C 函数指针;

我想我会建立一个字典关联到 VPInstance(void * 指针转换为整数)一些 PyEvent 类的实例应该包含自己的功能点击。使用它可以确保您需要一个 C 函数作为回调。

foo.pxd 中:

cdef class PyEvent(object):
cdef VPInstance instance
cdef object py_callback

foo.pyx 中: 事件=字典()

cdef void EventCallBack(VPInstance instance):
PyEvent ev = <PyEvent> dict[events[<size_t> self.instance]
ev.py_callback(ev)

cdef class PyEvent(object):
def __init__(self, click):
self.instance = vp_create()
self.py_callback = click

def event_set(self, eventname):
global events
events[<size_t> self.instance] = self
return vp_event_set(self.instance, eventname, EventCallBack)

我没有机会对此进行测试,所以我希望它能或多或少地起作用。此外,我建议在 cython-users@googlegroups.com 上询问,因为他们通常真的很有帮助,而且比我更专业。

关于python - 使用 cython 将回调函数从 python 传递到 c,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17870301/

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