GNAT follows standard calling sequence conventions and will thus interface to any other language that also follows these conventions. The following Convention identifiers are recognized by GNAT:
Ada
This indicates that the standard Ada calling sequence will be used and all Ada data items may be passed without any limitations in the case where GNAT is used to generate both the caller and callee. It is also possible to mix GNAT generated code and code generated by another Ada compiler. In this case, the data types should be restricted to simple cases, including primitive types. Whether complex data types can be passed depends on the situation. Probably it is safe to pass simple arrays, such as arrays of integers or floats. Records may or may not work, depending on whether both compilers lay them out identically. Complex structures involving variant records, access parameters, tasks, or protected types, are unlikely to be able to be passed.
Note that in the case of GNAT running on a platform that supports HP Ada 83, a higher degree of compatibility can be guaranteed, and in particular records are laid out in an identical manner in the two compilers. Note also that if output from two different compilers is mixed, the program is responsible for dealing with elaboration issues. Probably the safest approach is to write the main program in the version of Ada other than GNAT, so that it takes care of its own elaboration requirements, and then call the GNAT-generated adainit procedure to ensure elaboration of the GNAT components. Consult the documentation of the other Ada compiler for further details on elaboration.
However, it is not possible to mix the tasking run time of GNAT and HP Ada 83, All the tasking operations must either be entirely within GNAT compiled sections of the program, or entirely within HP Ada 83 compiled sections of the program.
Assembler
Specifies assembler as the convention. In practice this has the same effect as convention Ada (but is not equivalent in the sense of being considered the same convention).
COBOL
Data will be passed according to the conventions described in section B.4 of the Ada Reference Manual.
C
Data will be passed according to the conventions described in section B.3 of the Ada Reference Manual.
A note on interfacing to a C ‘varargs’ function:
In C,
varargs
allows a function to take a variable number of arguments. There is no direct equivalent in this to Ada. One approach that can be used is to create a C wrapper for each different profile and then interface to this C wrapper. For example, to print anint
value usingprintf
, create a C functionprintfi
that takes two arguments, a pointer to a string and an int, and callsprintf
. Then in the Ada program, use pragmaImport
to interface toprintfi
.It may work on some platforms to directly interface to a
varargs
function by providing a specific Ada profile for a particular call. However, this does not work on all platforms, since there is no guarantee that the calling sequence for a two argument normal C function is the same as for calling avarargs
C function with the same two arguments.
Default
Equivalent to C.
External
Equivalent to C.
C_Plus_Plus
(or CPP
)This stands for C++. For most purposes this is identical to C. See the separate description of the specialized GNAT pragmas relating to C++ interfacing for further details.
Fortran
Data will be passed according to the conventions described in section B.5 of the Ada Reference Manual.
Intrinsic
This applies to an intrinsic operation, as defined in the Ada Reference Manual. If a pragma Import (Intrinsic) applies to a subprogram, this means that the body of the subprogram is provided by the compiler itself, usually by means of an efficient code sequence, and that the user does not supply an explicit body for it. In an application program, the pragma may be applied to the following sets of names:
type Distance is new Long_Float; type Time is new Long_Float; type Velocity is new Long_Float; function "/" (D : Distance; T : Time) return Velocity; pragma Import (Intrinsic, "/"); This common idiom is often programmed with a generic definition and an explicit body. The pragma makes it simpler to introduce such declarations. It incurs no overhead in compilation time or code size, because it is implemented as a single machine instruction.
__builtin
functions
exposed by the GCC back-end, as in the following example:
function builtin_sqrt (F : Float) return Float; pragma Import (Intrinsic, builtin_sqrt, "__builtin_sqrtf");
Most of the GCC builtins are accessible this way, and as for other import conventions (e.g. C), it is the user’s responsibility to ensure that the Ada subprogram profile matches the underlying builtin expectations.
Stdcall
This is relevant only to Windows implementations of GNAT,
and specifies that the Stdcall
calling sequence will be used,
as defined by the NT API. Nevertheless, to ease building
cross-platform bindings this convention will be handled as a C
calling
convention on non-Windows platforms.
DLL
This is equivalent to Stdcall
.
Win32
This is equivalent to Stdcall
.
Stubbed
This is a special convention that indicates that the compiler
should provide a stub body that raises Program_Error
.
GNAT additionally provides a useful pragma Convention_Identifier
that can be used to parameterize conventions and allow additional synonyms
to be specified. For example if you have legacy code in which the convention
identifier Fortran77 was used for Fortran, you can use the configuration
pragma:
pragma Convention_Identifier (Fortran77, Fortran);
And from now on the identifier Fortran77 may be used as a convention
identifier (for example in an Import
pragma) with the same
meaning as Fortran.