Next: , Previous: Limitations When Using Ada DLLs from Ada, Up: Building DLLs with gnatdll


9.3.5.14 Exporting Ada Entities

Building a DLL is a way to encapsulate a set of services usable from any application. As a result, the Ada entities exported by a DLL should be exported with the C or Stdcall calling conventions to avoid any Ada name mangling. As an example here is an Ada package API, spec and body, exporting two procedures, a function, and a variable:

    with Interfaces.C; use Interfaces;
    package API is
       Count : C.int := 0;
       function Factorial (Val : C.int) return C.int;
    
       procedure Initialize_API;
       procedure Finalize_API;
       --  Initialization & Finalization routines. More in the next section.
    private
       pragma Export (C, Initialize_API);
       pragma Export (C, Finalize_API);
       pragma Export (C, Count);
       pragma Export (C, Factorial);
    end API;
    package body API is
       function Factorial (Val : C.int) return C.int is
          Fact : C.int := 1;
       begin
          Count := Count + 1;
          for K in 1 .. Val loop
             Fact := Fact * K;
          end loop;
          return Fact;
       end Factorial;
    
       procedure Initialize_API is
          procedure Adainit;
          pragma Import (C, Adainit);
       begin
          Adainit;
       end Initialize_API;
    
       procedure Finalize_API is
          procedure Adafinal;
          pragma Import (C, Adafinal);
       begin
          Adafinal;
       end Finalize_API;
    end API;

If the Ada DLL you are building will only be used by Ada applications you do not have to export Ada entities with a C or Stdcall convention. As an example, the previous package could be written as follows:

    package API is
       Count : Integer := 0;
       function Factorial (Val : Integer) return Integer;
    
       procedure Initialize_API;
       procedure Finalize_API;
       --  Initialization and Finalization routines.
    end API;
    package body API is
       function Factorial (Val : Integer) return Integer is
          Fact : Integer := 1;
       begin
          Count := Count + 1;
          for K in 1 .. Val loop
             Fact := Fact * K;
          end loop;
          return Fact;
       end Factorial;
    
       ...
       --  The remainder of this package body is unchanged.
    end API;

Note that if you do not export the Ada entities with a C or Stdcall convention you will have to provide the mangled Ada names in the definition file of the Ada DLL (Creating the Definition File).