Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I include a C++ class in a namespace into Cython?

Tags:

c++

cython

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;

    };
}
like image 728
Aaron de Windt Avatar asked Jan 21 '16 15:01

Aaron de Windt


People also ask

Does Cython use C or C++?

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.

What is Cimport Cython?

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.

What is Cdef extern?

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.


1 Answers

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.

like image 114
J.J. Hakala Avatar answered Sep 22 '22 02:09

J.J. Hakala