Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SWIG: Wrap call to C++ method with custom code?

Tags:

c++

python

swig

I'm trying to use SWIG directors to call Python code from C++. However if the code is running in another thread, I must acquire the GIL. My code looks roughly like this (minus the thread stuff):

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()

Swig:

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

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

How can I acquire the GIL before calling the Python callback?

To elaborate, the threads feature of SWIG creates code that releases the GIL when C++ code is called, but when Python code is called from C++ it isn't reacquired, so that's what I want to do.

The call stack looks like this: Python -> Foo.doSomething -> C++ -> Callback.call -> Python.

like image 900
bseibold Avatar asked Mar 21 '26 17:03

bseibold


1 Answers

Acquiring the GUIL is explained clearly in Non-Python created threads subsection of Thread State and the Global Interpreter Lock section in Python manual. But you say the issue is how to do this from SWIG generated code. How about this, added to your SWIG .i file:

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

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

You only need to expose PythonCallback (not Callback) and its lockedCall method, which you can rename to call if you wish via SWIG's %rename directive. Then in Python you would derive from PythonCallback, and override the call method (which in reality is the lockedCall method if you %rename'd it).

like image 102
Oliver Avatar answered Mar 23 '26 07:03

Oliver



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!