Creating a Stand-alone Library to be used in a non-Ada context (GNAT User’s Guide for Native Platforms)

#### 3.9.3.3 Creating a Stand-alone Library to be used in a non-Ada context ¶

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.