boost::python:使用回调
boost::python : using callback
我有这样的头文件(fingisdk.h):
#ifndef FINGISDK_H_
#define FINGISDK_H_
#include "fingienum.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*fingi_event)(FINGI_EVENT_ID eventId, char* msg);
FINGI_EVENT_ID start_fingi_sdk(char* ini_file_location);
FINGI_EVENT_ID download_room_info(char** roominfo);
void register_fingi_sdk_status_event_listener(fingi_event pointer_to_listener_fnc);
#ifdef __cplusplus
}
#endif
#endif
然后我为这个写了一个python包装器:
#include <fingisdk.h>
#include <fingienum.h>
#include <boost/python.hpp>
BOOST_PYTHON_MODULE(libpythonWrapper)
{
using namespace boost::python;
def("start_fingi_sdk", start_fingi_sdk);
}
调用它的python文件如下:
import libpythonWrapper
print libpythonWrapper.start_fingi_sdk('file_location.ini')
到目前为止,这一切都很好。然而,我不知道如何暴露双指针功能:
FINGI_EVENT_ID download_room_info(char** roominfo);
和回调函数:
void register_fingi_sdk_status_event_listener(fingi_event pointer_to_listener_fnc);
有人能给我指一些文件或帮我解决吗
谢谢
编辑1:
经过一番折腾,我终于找到了如何执行指针到指针的函数。Python不支持指针,因此必须包装download_room_info(char**roominfo)才能返回简单字符串:
std::string download_room_info_python_wrapper() {
char * value;
FINGI_EVENT_ID result = download_room_info(&value);
return std::string(value);
}
然后:
def("download_room_info", download_room_info_python_wrapper);
仍在寻找回调函数的解决方案
所以您想要将这个API绑定到Python:
typedef void (*fingi_event)(FINGI_EVENT_ID eventId, char* msg);
void register_fingi_sdk_status_event_listener(fingi_event);
这是一个寄存器函数,它接受一个函数,该函数接受一个eventId和一个字符串。好吧,让我们定义我们自己的一个(当然是外部"C",就像API一样):
void my_callback(FINGI_EVENT_ID eventId, char* msg)
{
// do something
}
现在我们可以为register函数编写一个包装器:
void my_register()
{
register_fingi_sdk_status_event_listener(my_callback);
}
并绑定它:
def("my_register", my_register);
这一切都应该奏效。但这是无用的,因为我们实际上在回调中没有做任何事情。这就引出了一个子问题,那就是你怎么可能在回调中做任何事情?我的一个想法是,您应该创建自己的函数注册机制,该机制允许您将Python回调函数注册到类似全局PyObject的东西中,该全局PyObject将被设置为Python函数并使用BoostPython:调用
boost::python::object g_callback;
void my_callback(FINGI_EVENT_ID eventId, char* msg)
{
if (g_callback)
g_callback(eventId, msg);
}
现在只需要让用户分配全局回调:
void set_callback(boost::python::object func)
{
g_callback = func;
register_fingi_sdk_status_event_listener(my_callback);
}
def("set_callback", set_callback);
然后在Python中:
def callback(eventId, msg):
print eventId, msg
set_callback(callback)
我想应该是这样。如果您的回调API像许多回调API一样支持"void*userData"参数,那么整个过程会简单得多。然后我们会使用它来存储PyObject或其他有用的东西。但API缺乏这一点,因此我们不得不在某个全局位置记住要调用哪个函数。
相关文章:
- 如何为Python Swigged C++对象创建和分配回调函数
- 通过 Boost Python 将 Python 函数转换为 C++,用作回调
- Python ctypes,回调函数增强类型是C++参考
- 在 Python 中打开 Maya callBacks 或C++查询内存中的所有回调
- 可以提升::p ython将对象的所有权传递给python回调函数
- boost::python:使用回调
- 如何使python函数作为c++函数的回调
- 无法停止来自python C扩展的python回调
- Cython:在DLL中注册用于回调的Python函数
- 在 Python 中扩展的 C++ 类中的 Seg 错误回调问题
- 在Python中使用回调时出错
- 从c++(或C)回调调用python方法
- Boost Python回调返回auto_ptr删除对象
- 嵌入python + numpy代码到c++ dll回调
- 使用boost::python从python传递回调到c++
- 提振.Python:类函数的回调
- Boost Python,传播c++回调到Python导致分段错误
- 当函数接受非平凡的参数时,C++通过SWIG用python回调
- Cython使用python-c-api调用回调segfault
- C++对Python的扩展:如何在C回调中确定Python函数名