来自 C++ 的 Python 回调 [英] Python callback from C++

查看:30
本文介绍了来自 C++ 的 Python 回调的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 C++ 类

class EventHandler {
virtual long readFromDaemon(void *buf, size_t count) = 0;
};

以及使用它的 Python 程序

and a Python program that uses it

class Handler(EventHandler):
    def readFromDaemon(self, buf, count):
    ...

C++ 代码调用 EventHandler::readFromDaemon().SWIG 转换参数并调用 Python 的 readFromDaemon():

C++ code calls EventHandler::readFromDaemon(). SWIG converts arguments and calls Python's readFromDaemon():

long SwigDirector_EventHandler::readFromDaemon(void *buf, size_t count) {
  ...
  swig::SwigVar_PyObject obj0;
  obj0 = SWIG_NewPointerObj(SWIG_as_voidptr(buf), SWIGTYPE_p_void,  0 );

  swig::SwigVar_PyObject obj1;
  obj1 = SWIG_From_size_t(static_cast< size_t >(count));
  ...
  swig::SwigVar_PyObject swig_method_name = SWIG_Python_str_FromChar((char *)"readFromDaemon");
  swig::SwigVar_PyObject result = PyObject_CallMethodObjArgs(swig_get_self(), (PyObject *) swig_method_name ,(PyObject *)obj0,(PyObject *)obj1, NULL);

我想将 (void *buf, size_t count) 转换为 PyBytesObject

I want to convert (void *buf, size_t count) to PyBytesObject

def readFromDaemon(self, buf):
    # buf is bytes

但我没有找到实现它的方法.

But I didn't found a way how to achieve it.

%typemap(in) (void *buf, size_t count) { ... } does not help.

推荐答案

我在这里找到了另一个主题的决定.

I found a decision in another topic here.

%typemap(directorin) (void *buf, size_t count) {
    $input = PyBytes_FromStringAndSize(static_cast<char*>($1), $2);
}

但是还有一个问题.内存缓冲区从 C++ 复制到 Python 对象.如何将字节从python对象复制回C++?从 python 2.7 开始有内存视图,但是 2.6 和旧版本怎么办?

But there is another problem. The memory buffer is copied from C++ to Python object. How to copy bytes back from python object to C++? There is memoryview since python 2.7, but what to do with 2.6 and olders versions?

为了清晰起见,这是调用 EventHandler::readFromDaemon 的 C++ 代码

This is C++ code that calls EventHandler::readFromDaemon, for clarity

std::vector<char> buf(maxlen);
long cnt = m_evt_handler->readFromDaemon(&buf[0], buf.size());

这是现在的包装代码

long SwigDirector_EventHandler::readFromDaemon(void *buf, size_t count) {
  long c_result;
  swig::SwigVar_PyObject obj0;
  {
    obj0 = PyBytes_FromStringAndSize(static_cast<char*>(buf), count);
  }
  ...

这篇关于来自 C++ 的 Python 回调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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