如何创建和分配Python Siggc++ C++对象的回调函数

2024-05-14 21:24:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个SwitGe+C++类(充当事件插件),它将指针携带到可分配的回调函数,例如

typedef void (*PluginEvent)(void* data1, void* data2);

class PluginWithEvents :  public Plugin
{
    public:
        bool assignOnProgressEvent(PluginEvent pluginsProgress, void* userData1 = nullptr, void* userData2 = nullptr);
        void workProgressEvent(void* data1, void* data2);
    protected:
        PluginEvent mWorkProgressEvent;
        void* mWorkProgressData1;
        void* mWorkProgressData2;
};

和实现代码

^{pr2}$

问题是,在Python中使用这个类时,如何定义要传递给assignProgressEvent函数的回调函数?在

以下Python代码给出了错误:

NotImplementedError: Wrong number or type of arguments for overloaded 
function 'PluginWithEvents_assignOnProgressEvent'.

Possible C/C++ prototypes are:
PluginWithEvents::assignOnProgressEvent(dsl::PluginEvent,void *,void *)
PluginWithEvents::assignOnProgressEvent(dsl::PluginEvent,void *)
PluginWithEvents::assignOnProgressEvent(dsl::PluginEvent)

Tags: 函数代码插件事件publicdsl指针void
1条回答
网友
1楼 · 发布于 2024-05-14 21:24:53

我准备了一个我在评论中提到的例子。它变得相当可怕,而且可能相当脆弱。有很多地方可以显著改进错误检查。在

在接口文件中,我包含了后端代码(test.hpp),这或多或少就是您问题中的代码,以及Python回调所需的工具。所有讨厌的细节都隐藏在python_callback.hpp中。在

然后,我声明一个全局变量callback,它保存当前回调,而函数{}调用回调。您已经注意到这种方法的一个缺点。在任何时候,飞行中最多可以有一个回调。所以不要向一个函数传递多个回调函数,也不要保留对callback的引用或指针(复制可能没问题,但不能保证)。在

其余的是PytMaPS,将Python函数映射到C++函数指针。在


test.i

%module example
%{
#include <iostream>

#include "test.hpp"
#include "python_callback.hpp"

PythonCallback callback;

void callback_caller(void *, void *) {
    double pi = callback.call<double>("ABC", 3.14, 42);
    std::cout << "C++ reveived: " << pi << '\n';
}
%}

%include <exception.i>
%exception {
  try {
    $action
  } catch (std::exception const &e) {
    SWIG_exception(SWIG_RuntimeError, e.what());
  }
}

%typemap(typecheck) PluginEvent {
    $1 = PyCallable_Check($input);

}
%typemap(in) PluginEvent {
    callback = PythonCallback($input);
    $1 = &callback_caller;
}

%include "test.hpp"

test.hpp

^{pr2}$

python_callback.hpp

<>这个文件非常不完整,因为所有不同的Python和C++类型之间的映射都不见了。我添加了一些映射(PyFloatdouble,PyInttoint, PyString到{}),为您提供了一个如何用自己的映射扩展代码的蓝图。在

^{3}$

我们可以使用一个小脚本测试上面的设置,希望打印“Hello World!”. 在

test.py

from example import *

p = PluginWithEvents()

def callback(a, b, c):
    print("Hello World!")
    print(a,type(a))
    print(b,type(b))
    print(c,type(c))
    return 3.14

p.assignOnProgressEvent(callback)
p.workProgressEvent(None,None)

我们试试吧

$ swig -c++ -python test.i
$ clang++ -Wall -Wextra -Wpedantic -std=c++11 -I /usr/include/python2.7/ -fPIC -shared test_wrap.cxx -o _example.so -lpython2.7
$ python test.py
Hello World!
('ABC', <type 'str'>)
(3.14, <type 'float'>)
(42L, <type 'long'>)
C++ reveived: 3.14

相关问题 更多 >

    热门问题