ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

boost :: python:使用回调

2019-11-22 05:08:16  阅读:341  来源: 互联网

标签:boost-python python c-4


我有这样的头文件(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和一个字符串的函数. OK,让我们定义一个我们自己的(当然,在外部“ 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之类的东西中,它将被设置为Python函数并使用Boost Python进行调用:

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缺少此功能,因此我们在某个地方使用全局变量来记住要调用的函数.

标签:boost-python,python,c-4
来源: https://codeday.me/bug/20191122/2057273.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有