python - SWIG:使用自定义代码包装对 C++ 方法的调用?

标签 python c++ swig

我正在尝试使用 SWIG Controller 从 C++ 调用 Python 代码。但是,如果代码在另一个线程中运行,我必须获取 GIL。我的代码大致如下(减去线程内容):

struct Callback {
  virtual ~Callback() {}
  virtual void call() {} // will be overwritten in Python
};

struct Foo {
    Callback *c;
    Foo(Callback* c) : c(c) {}
    void doSomething() { c->call(); } // being called from another thread
};

Python:

from demo import *
class MyCallback(Callback):
    def call(*args):
        print("python callback")

c = MyCallback()
f = Foo(c)
f.doSomething()

痛饮:

%module(directors="1", threads="1") demo
%feature("director");

%{
#include <test.h>
%}
%thread;
%include <test.h>

如何在调用Python回调之前获取GIL?

详细来说,SWIG 的 threads 功能会创建在调用 C++ 代码时释放 GIL 的代码,但是当从 C++ 调用 Python 代码时,它不会被重新获取,所以这就是我想要的做。

调用堆栈如下所示:Python -> Foo.doSomething -> C++ -> Callback.call -> Python。

最佳答案

Non-Python created threads 中清楚地解释了获取 GUIL Python 手册中线程状态和全局解释器锁部分的小节。但你说问题是如何从 SWIG 生成的代码中做到这一点。怎么样,添加到您的 SWIG .i 文件中:

struct PythonCallback: public Callback
{
  virtual void call() { 
     getGIL();
     lockedCall();
     releaseGIL();
  } 

  virtual void lockedCall() {} // will be overwritten in Python
};

您只需要公开 PythonCallback (不是 Callback)及其 lockedCall 方法,如果您愿意,可以通过 SWIG 将其重命名为 call %rename 指令。然后在Python中,您可以从PythonCallback派生,并覆盖call方法(实际上是lockedCall方法,如果您%rename 了)。

关于python - SWIG:使用自定义代码包装对 C++ 方法的调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23613488/

相关文章:

Python 脚本按流使用 Azure 存储 Blob 中的数据,并按流更新 Blob,无需本地文件读取和上传

python - 单击鼠标按钮时如何连续移动字符

python - 如何为 bin 目录中的脚本编写 Python 单元测试

c++ - 无法将字符串从命令行转换为 float 组

python - 创建包含成对的另一个列表的列表?

python - Py_Finalize() 导致 Python 3.9 的段错误但不是 Python 2.7

c++ - 将 make_unique<X> 分配给 shared_ptr<X>

python - 为什么当通过 swig 从子进程调用时,使用 OpenMP 的共享库中的函数会挂起?

java - 如何在 SWIG 生成的 Java 绑定(bind)中转换为 SWIGTYPE_p_void 类型?

c++ - 用 swig 包装专门的 c++ 模板类