# Ada Programming/Libraries/Interfaces.C

This language feature is available from Ada 95 on.
Interfaces.C is a unit of the Predefined Language Environment since Ada 95.
Let's see the use of this package and its children through two examples, one for C and another for C++.

## Example for C

PCRE is a popular C-library that implements regular expression pattern matching using the same syntax and semantics as Perl 5. PCRE means Perl Compatible Regular Expressions. The site of this library is pcre.org
Within Gnat, there are Ada library for regular expressions : Unix-style : GNAT.Regexp, GNAT.Regpat and Spitbol-like : GNAT.Spitbol.
As an alternative, interfacing with PCRE will show some techniques for dealing with a C library. There are enough primitives inside the package Interfaces.C.Strings to avoid a wrapper in C.

### Abstract of header file pcre.h

Using version 8.02 of the file. The header file is quite long, we will just use 2 types and 4 operations, so what we need is just

### Interface of the thin binding

The objective of the interface is to hide the dependency from the package Interfaces.C. and the types exposed by the interface are : Integer, String, Pcre_Type, Extra_type, (and also System.Address in the complete binding).
The types Pcre and Extra are opaque pointers and should not be accessible outside the interface so they are made private. No operation on the components of pcre_extra are necessary, so pcre and pcre_extra are just declared as System.Address.
The complete cycle in PCRE is (compile/study/exec) where Gnat.Regex has 2 phases (compile/match); the study phase is an optimization of the pattern, that output an object of type Extra. Here we by-pass the study phase.
Compile allocates and returns a pointer to the compiled pattern, that is null if some error occurred. In that case, an error message is available as well as the position of the error.
Free is used to deallocate the compiled pattern.
Match takes as inputs the compiled pattern, the subject Ada string to parse. The parameter length of string is necessary in case of partial scan.
procedure Match ouputs a return code (Result) that is negative if there is no match or an error. For a zero or positive return code, the match_array has the same output as the C library.

#### pcre.ads
### Implementation of the thin binding

In C, a string is implemented as a pointer to char terminated by a nul. Using Gnat, an Ada string is implemented with the 2 bounds first, and afterwards the content of the string.
The function Interfaces.C.New_String
This function allocates a new copy of the data and adds a terminating null. So the data are duplicated, which can be a burden when the data weight 50 Mb.
Also to avoid a memory leak, this data must be freed after use.
The procedure Match deals with :
Due to the difference between the Ada string and the C string, the trick is to point to the first element of the Ada String. In this case, there is no terminating nul, but as we pass the length of the data, this is no trouble.
Ada allocates this vector that is used by the C code. Therefore a pragma Convention(C) is required for the vector, as well as a pragma Volatile so that the Ada compiler does not interfere/optimize it.
The whole package has been tested for memory leaks with Valgrind and does not leak.

#### pcre.adb
### Test of Pcre binding

Example taken from Regex at the site Rosetta.org

#### test_0.adb

Output :

### Complete code of the binding

The complete code of the binding and some examples can be download at sourceforge.net

## Example for C++

How to use C++ functions from Ada. Please consider the following C++ code:

### source file random_number.cpp

How can we call the C++ function getRandomInt(0,10) from an Ada program?

### The solution

Start by creating an Ada specification based on the C++ header file (assuming a suitably recent GCC):
Or read this for examples on auto-generating Ada bindings from C and C++ headers.
Comment out the #includes in random_number.h. They are unused and they are repeated in random_number.cpp anyway. Save it as random_number.hpp. (This forces C++ style Ada specs rather than C style, which is essential to link to the C++ code). Generate the Ada specification automatically:
This produces the file random_number_hpp.ads.

#### random_number_hpp.ads

While not essential, it is recommended to write a wrapper package to hide the C interface and C types, and to make the interface look like Ada: random_wrapper.ads and random_wrapper.adb. (This constitutes a "thick binding", while package random_number_h is a thin binding). At this point you can choose what to expose to the Ada code; I have been selective (or lazy!).

#### random_wrapper.adb

Now write your main Ada program:

#### random.adb

Compile the C++ portion (more complex examples may need a Makefile):
Build the Ada portion:
Note additional arguments -largs ./random_number.o -lstdc++ to gnatlink; extend these if you add more C++ objects and libraries.
Run it.

## See also
### Wikibook

* Ada Programming/Libraries/Interfaces
* Ada Programming/Libraries/Interfaces.C.Strings

### External examples

* Search for examples of Interfaces.C in: Rosetta Code, GitHub (gists), any Alire crate or this Wikibook.
* Search for posts related to Interfaces.C in: Stack Overflow, comp.lang.ada or any Ada related page.

### Ada Reference Manual
#### Ada 95

* B.3: Interfacing with C

#### Ada 2005

* B.3: Interfacing with C and C++

#### Ada 2012

* B.3: Interfacing with C and C++

### Open-Source Implementations

FSF GNAT
* Specification: i-c.ads
* Body: i-c.adb
drake
* Specification: interfaces/i-c.ads
* Body: interfaces/i-c.adb