Search code examples
pythonc++headercythontranspiler

Cython: How to export C++ class to .hpp header instead of C .h header


This works fine in .pxd file:

cdef public:
    struct foo:
        float bar

But this doesn't work:

cdef public:
    class foo:
        float bar # Syntax error in simple statement list

This works but Cython is still making struct instead of class and the resulting file is .h file instead of .hpp (or .hh) file:

cdef public:
    cppclass foo:
        float bar

My file is called mod.pyx and Cython transpiles the cppclass right above as:

#ifndef __PYX_HAVE__mod
#define __PYX_HAVE__mod

#include "Python.h"
struct foo;
struct foo {

  /* "mod.pyx":21
 *
 * cdef public:
 *     cppclass foo:             # <<<<<<<<<<<<<<
 *         float bar
 *
 */
  float bar;
};

How to make real C++ output from Cython transpilation? I mean .hpp or .hh files with class keyword inside. It's possible to use a separate C++ header file instead but I would like to make the source code fully Cython.

The transpile command is:
cython3 -3 --cplus --fast-fail mod.pyx


Solution

  • I've figured out how to define C++ class (not the Python extension type 'class') in Cython only; it is still transpiled to .h file as struct but with methods inside:

    # Declaration
    cdef public:
        cppclass foo:
            float bar
            foo() # Constructor
            method() # Sample method
    
    # Implementation
    cdef cppclass foo:
        method():
            cdef foo* p = this # 'this' can be used
            print(p.bar+1) # Test
    

    There are some notes:

    • The nullary constructor is a must, Cython says so
      • This doesn't require constructor: cdef foo* f = new foo()
      • This requires a constructor: cdef foo f = foo()
        • Or error: no constructor found for C++ type 'foo'
    • No overloads in Python, which applies to Cython and so no constructor overloads (?); properties to be set by a method instead