SWIG:用自定义代码包装调用C ++方法?

时间:2014-05-12 15:50:09

标签: python c++ swig

我正在尝试使用SWIG导向器从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代码时,它不会被重新获取,所以这就是我想要做的。 / p>

调用堆栈如下所示:Python - &gt; Foo.doSomething - &gt; C ++ - &gt; Callback.call - &gt;蟒。

1 个答案:

答案 0 :(得分:2)

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

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

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

您只需要公开PythonCallback(而不是回调)及其lockedCall方法,如果您希望通过SWIG&{39} call将其重命名为%rename指示。然后在Python中,您将从PythonCallback派生,并覆盖call方法(如果您lockedCall,则实际上是%rename方法)。