Reputation: 51
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
Reputation: 1
To pass class by reference:
def kungFoo(self,pyFoo f):
self.thisptr.kungFoo(f.thisptr[0])
Upvotes: 0
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
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