user3173710
user3173710

Reputation: 51

How do I pass one C++ class (reference) to another when using Cython?

I'm trying to wrap a C++ module using Cython such that I can use it in Python.

The module has multiple classes some of these have methods that have object references to another class as arguments.

So lets say I have c++ classes called "foo" and "bar"- and cython wrap them thus:

cdef extern from "foobar.hpp" namespace "foobar":
    cdef cppclass foo:
        pass
    cdef cppclass bar:
        void kungFoo(foo &f)

Now I want to make a wrapper class so that I can use it in Python...

cdef class pyFoo:
    cdef foo *thisptr
    def __cinit__(self):
        self.thisptr = new foo()

cdef class pyBar:
    cdef bar *thisptr
    def __cinit__(self):
        self.thisptr = new bar()
    def kungFoo(self, f):
        self.thisptr.kungFoo(f.thisptr)

Well this results in "Error compiling Cython file." and "Cannot convert Python object to 'foo'".

I think that this is because the cdef cppclass foo makes foo a "Python object" associated with the c++ class. However, this clever transformation doesn't seem to go back the other way when I need to pass it as an argument to another c++ class.

This seems like a basic issue with cython to me - but I can't seem to find any solution after a couple of hours on google.

Any help most welcome.

Thanks!

Upvotes: 5

Views: 2055

Answers (3)

Nicolas Kuske
Nicolas Kuske

Reputation: 1

To pass class by reference:

    def kungFoo(self,pyFoo f):
         self.thisptr.kungFoo(f.thisptr[0])

Upvotes: 0

Zachary Kraus
Zachary Kraus

Reputation: 1101

The second section of code of the above answer should work but you may need to modify it since you are passing by reference. You can either modify to pass by pointer in which no modifications will need to be made or you can import the dereference cython module to turn the pointer to the object and assign the object to the reference.

An example of how to use dereference is shown in the answer on Cython and c++ class constructors

Hopefully this will help you. This problem took me many hours to solve and the above page was extremely helpful.

Upvotes: 0

Czarek Tomczak
Czarek Tomczak

Reputation: 20675

Specify type for the f parameter. So make it this:

def kungFoo(self, foo &f):
    self.thisptr.kungFoo(f)

Or this:

def kungFoo(self, pyFoo f):
    self.thisptr.kungFoo(f.thisptr)

Upvotes: 2

Related Questions