我正在尝试使用 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/