|
This chapter provides some basic explanations related to the interface between the C++ core library and the Ada core library as well as between the general-purpose C++ library and Python libraries. This information might be of interest to those developers who maintain or evolve these interfaces on their own or who want to extend the project with support for other programming languages.
The binding between C++ core and Ada core libraries benefits from the Ada's ability to link with C object files. This ability is part of the Ada language standard and implicitly expects some technical correspondence between the Ada compiler and some C compiler. The proper choice of the C compiler is particularly easy with the GNAT Ada compiler, as GNAT is part of the GCC tool-chain and its natural counterpart for inter-language linking is gcc - both compilers produce object code that can be linked together using a single linker from the same tool-chain.
In order to avoid problems related to name mangling that is internally introduced by the g++ compiler and to keep the interaction between two programming languages within the constraints of simple types that are addressed by the Ada standard, a very thin interfacing layer of extern "C"
functions was added in the core library.
It is this layer that is accessed from the Ada core library and could, in principle, also form a basis for bindings with other programming languages that have the ability to link with C object files.
The thin interfacing layer is entirely implemented in the src/core/c_interface.cpp
source file and is inherently embedded in the core static library. The interfacing layer is not accompanied by any header file. The reason for this is that languages that interface with C at the linker level do not need to access any header files and rely only on the visibility of given symbols in the object file.
At the Ada core level, the interfacing stubs are introduced in terms of appropriate import pragmas.
The approach for inter-language interfacing is similar in the Python binding, where a wrapping layer was defined for the general-purpose C++ library in terms of the C interface. Thanks to this, most of the functionality of the C++ library is available to code that relies on the C calling convention.
The wrapper module for Python is implemented in the src/python/yami4py.cpp
source file, and is built as a dynamically loaded library with two alternative wrapping interfaces, with and without the use of standard Python extension API. In the first case the module is loaded and bound directly within the Python interpreter, while in the second case the standard ctypes
package is used as a binding layer for functions that are dynamically identified by name.