I'm trying to create a wrap for a set C++ classes so I can use it in Python using Cython. This is what I have tried so far.
cdef extern from "HilClass.h" namespace "acro":
cdef cppclass _HilClass "HilClass":
void start()
cdef class HilClass:
cdef _HilClass *ptr
cpdef start(self):
self.ptr.start()
That doesn't compile. I get the errors below, which by now I've come to learn that a possible cause is that it doesn't find the class. So after checking I had properly included the headers and sources I looked into the .cpp generated by Cython. I searched for acro
but was unable to find it. It wasn't mentioned anywhere in the code.
error C2143: syntax error: missing ';' before '*'
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
error C2238: unexpected token(s) preceding ';'
... (more warning and errors related to HilClass)
This is when I decided to change the second line to.
cdef cppclass _HilClass "acro::HilClass":
This does compile. But this wasn't done in any example/tutorial I've found. So my question is, I'm I missing something and will my 'workaround' keep working reliably.
NOTE: I'm not interested in creating an instance of this class from within Python or Cython, I just need it to wrap around a HilClass pointer.
EDIT:
This is the code inside 'HilClass.h'. 'acrophobe.h' has a few class forward declarations, enums, typedef unint#_t ####
, and includes stdint.
#include "acrophobe.h"
namespace acro {
class HilClass
{
public:
HilClass(AcrophobeClass *acro_ptr);
~HilClass();
HILSocketClass *sck;
void start();
void acrophile_iteration(char dest, lbp::PortID_t PortID);
void set_activity_iteration_start(bool s);
// More of these set_activity functions
void set_activity_logging(bool s);
private:
AcrophobeClass *acro;
};
}
Cython can call into both C and C++ code, and even subclass C++ classes. The C++ support is somewhat limited, though, given how complex the C++ language is.
The cimport statement is used in a definition or implementation file to gain access to names declared in another definition file. Its syntax exactly parallels that of the normal Python import statement. When pure python syntax is used, the same effect can be done by importing from special cython.
The cdef extern from clause does three things: It directs Cython to place a #include statement for the named header file in the generated C code. It prevents Cython from generating any C code for the declarations found in the associated block.
You need to define as you have done
cdef cppclass _HilClass "acro::HilClass"
because you are giving acro::HilClass an alias _HilClass. You could test what happens if you define
cdef cppclass HilClass:
void start()
and then later (the class name is just for an example)
cdef class PyHilClass:
cdef HilClass * ptr
I don't see any reason why your solution would not be reliable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With