6

How do I expose a python objects to C++ using cython? I understand how it can be done for functions, but not sure if this is even possible for a class.

Essentially, I have a data structure which is written in cython which has to be populated by C++. Once populated, c++ code will call a cython method and pass that object. The cython code in that method should be able to access the object's data.

2
  • 3
    docs.cython.org/src/userguide/wrapping_CPlusPlus.html Commented Feb 16, 2016 at 14:51
  • @SimonKraemer Thanks. It worked for me. I am still wondering if we really have to write those wrapper code manually (The pyx file for python class and the pxd file). Cant they be generated? In my requirement, the stuff I will have to expose to python are quite extensive and involve custom classes, std container, etc and manually writing all these wrapper code does not seem to scale. Commented Feb 16, 2016 at 17:28

1 Answer 1

8

The answer is to use "public extension types".

A trivial example is:

cdef extern from "cpp_file.hpp":
    void modifyMyClass(MyClass)

cdef public class MyClass [object TheNameThisWillHaveInC, type TheNameTheTypeWillHaveInC]:
    cdef int a
    cdef int b
    
def example():
    cdef MyClass a = MyClass()
    modifyMyClass(a)

Note the "public class MyClass". You also need to specify two names: one for the name of the struct used to represent MyClass, and one for the name that the type object will have.

Running Cython on it generates a header file containing the following (I've only copied the interesting bits).

struct TheNameThisWillHaveInC {
  PyObject_HEAD
  int a;
  int b;
};

__PYX_EXTERN_C DL_IMPORT(PyTypeObject) TheNameTheTypeWillHaveInC;

You simply include that header file in your C++ code. The example function I've given would appear as follows in C++:

void modifyMyClass(TheNameThisWillHaveInC* obj) {
   obj->a = 5; // etc
}

I don't think the fact that you're using C++ rather than C changes much. The only thing you'd need to do is run Cython in C++ mode (specify the language in setup.py to avoid name mangling issues.

Sign up to request clarification or add additional context in comments.

1 Comment

very useful. thanks, @DavidW! I do get a fun warnings like expected 'struct MyNode *' but argument is of type 'struct MyNode *' warning from gcc (and clang). That sent me down a long and ugly path but decided that it works and to move on. Leaving note for others passing by.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.