I have an instance of a class from SWIG-wrapped C++ library from which I would like to extract its reference, in order to be able to use it inside a Cython file, in which I am directly linking to the same C++ library by using a more lightweight self-made Cython wrapper of the same class.
I know it would not be as easy as accessing some hidden attribute, but I imagine there might be some function within SWIG or CPython that could potentially do that if linked to from within Cython (some PyObject_*, perhaps?).
Unfortunately, I don't know enough about SWIG or CPython internals to know how to do this, or whether this is really possible without modifying the source code of the SWIG binding.
After doing further research, I have figured out how to do what I wanted.
According to the documentation, SWIG-wrapped classes in Python consist of three layers: a) a pure Python instance, b) a custom SwigPyObject built-in type contained in its
.this
attribute and c) a normally inaccessible pointervoid *ptr
to the actual C++ instance contained therein, which is what Cython would require.In order to gain access to that pointer, I had to create a Cython wrapper of the SwigPyObject struct in order to access the internal
void *ptr
of the SWIG instance. The declaration of this struct is normally included directly into the SWIG-generated C++ source, and not as a separate header, so I created one to contain it:This include file is then referenced in the Cython
.pxd
file, to enable access to the internalptr
variable:The required pointer can now be referenced from inside the
.pyx
Cython source code:Caveat: Since SWIG-wrapped classes exist in both Python and C++ space, SWIG implements mechanisms to deal with the memory allocation, including information about the "ownership" of an instance for garbage collection. This code doesn't try to deal with any of this, so there might be a danger of running into allocation issues, but as long as a reference to the original SWIG instance is kept in Python, I believe it should be safe to manipulate it under Cython.