Using Pyrex with C++
This section describes some features of Pyrex that are designed to facilitate wrapping of libraries written in C++.
Source Filenames
Pyrex source files that use C++ features should be named with an extension of ".pyx+". The corresponding generated C file will then have an extension of ".cpp", and should be compiled with a C++ compiler.
Note that this only applies to implementation files, not definition files. Definition files should always have an extension of ".pxd", whether they use C++ features or not.
C++ Structs and Classes
C++ structs and classes are declared using cdef+ struct, for example,
cdef extern from "somewhere.h":
cdef+ struct Shrubbery:
__init__()
__init__(float width)
__init__(float width, int price)
float width
int height
void plant_with_rhododendrons(int howmany)
Some important things to note:
- All cdef+ struct declarations must appear inside a cdef extern from block.
- In Pyrex, struct is used regardless of whether the type is declared as a "struct" or a "class" in C++.
- Constructors are declared using the name __init__. There can be multiple constructors with different signatures. If no constructor is declared, a single constructor with no arguments is assumed.
- Destructors are not declared in Pyrex.
- Member functions are declared without "virtual", whether they are virtual in C++ or not.
A whole extern from block can also be declared using cdef+ if desired. This can be convenient when declaring a number of C++ types at once.
cdef+ extern from "shrubbing.h":
struct Shrubbery:
...
The effect is the same as if cdef+ had been used on all the contained struct declarations. Other declarations appearing in the block are treated as ordinary cdef declarations.
Inheritance
A C++ struct may inherit from one or more base structs.
cdef+ extern from "shrubbing.h":
struct FancyShrubbery(Shrubbery):
...
Instantiation
C++ structs can be instantiated using the new operator, similarly to C++.
cdef Shrubbery *sh1, *sh2, *sh3
sh1 = new Shrubbery()
sh2 = new Shrubbery(3.2)
sh3 = new Shrubbery(4.3, 800)
Note that parentheses are required even if there are no arguments.
Disposal
The del statement can be applied to a pointer to a C++ struct to deallocate it. This is equivalent to delete in C++.
cdef Shrubbery *big_sh
big_sh = new Shrubbery(42.0)
display_in_garden_show(big_sh)
del big_sh
Overloaded Functions
Apart
from the special case of C++ struct constructors, there is no special
support for dealing with overloaded functions in C++. You will need to
declare each version of the function with a different name in Pyrex and
use C name specifications to map them all to the same C++ name. For
example,
cdef extern from "shrubbing.h":
void build_with_width "build_shrubbery" (float width)
void build_with_petunias "build_shrubbery" (int number_of_petunias)