Yet ANother Interface between C++ and python¶
Warning
Very experimental. I probably shouldn’t have written my own code to interface python and C++, but I did anyway, and here it is.
yanic: <interface file> <c++ output prefix> <python prefix> <rst
prefix>
Guide for interface files¶
[]
arguments are optional<>
arguments are required and do not have any whitespace{}
arguments can have whitespace but no carriage returns
Types, e.g. {type}, {parameter type}, {return type} are specified in the following way:
[static] [const] [std::shared_ptr] <type name> [*] [&] [**]
Non-alphabetic characters in class names are always converted to underscores. Other type decorators are not yet supported.
Comments (all lines beginning with #
are comments). Comments may
appear anywhere, including inside a class or function definition.
Header items¶
Namespace specification:
namespace <name>
The namespace is used to name the automatically name the
extern C
functions which access the class. The namespace is assumed to apply to all classes and functions which follow.Template for class documentation, using
%name%
to refer to the class name. Specified either as:py_class_doc {}
or as:
py_class_doc | | {} | {} ...
Name of dll to load:
dll_name <name>
This is the name of the python data member in the
link
class which holds the ctypes.CDLL object.Header for .rst files:
rst_header {}
or:
rst_header | | {} | {} ...
Include statements for C++ header file:
h_include <file (including quotes or angle brackets)>
Many include files can be specified with many include statements and all of them will be included at the top of the generated .h files.
Include statement for C++ source code:
cpp_include <file (including quotes or angle brackets)>
Many include files can be specified with many include statements and all of them will be included at the top of the generated .cpp files. At least one is required to find the generated .h file.
Namespaces to use in C++ source code:
cpp_using <namespace>
Additional python header lines:
py_header {}
For example, this can include import statements or definitions of other global objects.
Functions¶
Function definitions:
function <function name> - {return type} - py_name <python name> - {parameter type} <parameter name> [default value] ...
For each function, an
extern C
wrapper is created with the suffix_wrapper
and then a python function is created to call that wrapper. The python name is optional, but when present must be after the return type and before the variable list.
Classes¶
Class definitions:
class <class name> ["abstract"]
If the
abstract
label is appended, then__init__()
is tagged as an@abstractmethod
in python. If the class is not abstract and theno_def_cons
tag is not given (see below), then acreate
function is created to create an object. Afree
function is always created to destroy an object. Ifstd_cc
is specified, then a C function namedcopy
is created along with an analogous__deepcopy__
python method which wraps around the default C++ copy constructor.Python name of class (optional):
- py_name <name>
Optional line which should be specified if the class defines both
class (const class &)
andclass &operator=(const class &)
. This allows one to define the python__deepcopy__
method:- std_cc
Optional line which should be specified if the class has no default constructor:
- no_def_cons
Parent class (multiple parents not currently supported):
- parent <parent class name>
Python documentation for this class (overrides template specification above which doesn’t have a hyphen):
- py_class_doc {}
or:
- py_class_doc | | {} | {} ...
Class member data:
- {type} <name>
Get and set methods for class member data are generated. For standard C types,
std::string
objects, and shared pointer objects, the get and set methods pass by value (i.e. they imply a copy). For classes from the interface, the get methods return references and the set methods pass by value.Class member function definitions are of the following form. The return type and parameter specifications must begin with two spaces:
- function <function name> - {return type} - {parameter type} <parameter name> [default value] ...
Extra python code for the class:
- extra_py {}
or:
- extra_py | | {} | {} ...
The extra python code is prepended by four spaces to conform with the indentation style used by yanic.
Class constructor with parameters. The parameter specifications must begin with two spaces:
- cons <python constructor name> - py_name <python name> - {parameter type} <parameter name> ...
Other objects¶
Specification of a shared pointer:
- shared_ptr <class name>
Shared pointers imply the creation of a
create
function to create a shared pointer to a default object, afree
function to free the memory associated with the shared pointer (which may or may not free the underlying object), and a pointer function which gets a raw pointer to the underlying object. Using shared pointers for objects which do not have a default constructor is not yet supported.Python name of class for the shared pointer (must begin with two spaces):
- py_name <name>
Constraints¶
Global functions and member functions may be overloaded, but only if they are given different python names.
Todos¶
Todo
In yanic:
Need to fix function names in case where there is no namespace.
Simplify code duplication in parsing: reading global and member functions should be the same
Allow use of numpy.arange for uniform_grid arguments
Document .i format
Make sure data members named ‘del’ are properly renamed without hacking, e.g. with a py_name argument
Make sure negative size_t arguments are rejected in python
Details¶
Handling of function arguments:
C type (bool, char, double, float, int, size_t): Convert from a Python object to
ctypes.c_<type>
in the Python wrapper.reference to C-type: The handling of these references depends on whether the reference is labeled as
io
(input and output) orout
(output only). These references are included in return values in the python wrapper function, and if the labelio
is given, then they are also input parameters.pointer to C-type: not yet implemented
std::string
: Usechar *
in C the wrapper. Convert python string to bytes object and then to char * in python code.reference to
std::string
: Usevoid *&
in the C wrapper …std_vector & - table::line_of_data: convert to an std::vector<double>
std::vector<double> & - uniform_grid::vector
Return values:
C type bool: return Python
True
orFalse
C type char: return a one-character bytes object
C type double or float: return a Python float
C type int or size_t: return a Python int
reference to C type: this is supported currently only for operator[] and operator()
std::string
: Return a Python bytes objectstd::string &
: Return a std_string object
Special functions:
Array-indexing,
operator[]
functions are translated to__getitem__
functions on the python side. If theoperator[]
function returns a non-const reference rather than a value, then a__setitem__
function is also created.