It’s easy for you to adapt the SAL build procedure discussed above for use of a SAL in a non-Ada context.
The only extra step required is to ensure that library interface subprograms
are compatible with the main program, by means of pragma Export
or pragma Convention
.
Here’s an example of simple library interface for use with C main program:
package My_Package is procedure Do_Something; pragma Export (C, Do_Something, "do_something"); procedure Do_Something_Else; pragma Export (C, Do_Something_Else, "do_something_else"); end My_Package;
On the C side, you must provide a ‘foreign’ view of the library interface; remember that it should contain elaboration routines in addition to interface subprograms.
The example below shows the content of mylib_interface.h
(note
that there is no rule for the naming of this file, any name can be used)
/* the library elaboration procedure */ extern void mylibinit (void); /* the library finalization procedure */ extern void mylibfinal (void); /* the interface exported by the library */ extern void do_something (void); extern void do_something_else (void);
Libraries built as explained above can be used from any program, provided
the elaboration procedures (named mylibinit
in the previous
example) are called before any library services are used. Any number of
libraries can be called from a single executable as long as the elaboration
procedure of each library is called.
Below is an example of a C program that uses the mylib
library.
#include "mylib_interface.h" int main (void) { /* First, elaborate the library before using it */ mylibinit (); /* Main program, using the library exported entities */ do_something (); do_something_else (); /* Library finalization at the end of the program */ mylibfinal (); return 0; }
Note that invoking any library finalization procedure generated by
gnatbind
shuts down the Ada run-time environment.
Consequently, the
finalization of all Ada libraries must be performed at the end of the program.
No call to these libraries or to the Ada run-time library should be made
after the finalization phase.
Information on limitations of binding Ada code in non-Ada contexts can be found under Binding with Non-Ada Main Programs.
Note also that you must take special care with multi-tasking applications. In that case, the initialization and finalization routines are not protected against concurrent access. If you need such requirement, you must ensure it at the application level using a specific operating system services like a mutex or a critical-section.