Interfaces#
Package Interfaces is the parent of several library packages that declare types and other entities useful for interfacing to foreign languages. It also contains some implementation-defined types that are useful across more than one language (in particular for interfacing to assembly language).
package Interfaces
with Pure is
type Integer_n is range -2**(n-1) .. 2**(n-1) - 1; -- 2's complement
type Unsigned_n is mod 2**n;
function Shift_Left (Value: Unsigned_n; Amount: Natural) return Unsigned_n;
function Shift_Right (Value: Unsigned_n; Amount: Natural) return Unsigned_n;
function Shift_Right_Arithmetic(Value: Unsigned_n; Amount: Natural) return Unsigned_n;
function Rotate_Left (Value: Unsigned_n; Amount: Natural) return Unsigned_n;
function Rotate_Right (Value: Unsigned_n; Amount: Natural) return Unsigned_n;
end Interfaces;
- Signed and modular integer types of n bits, if supported by the target architecture, for each n that is at least
the size of a storage element and that is a factor of the word size. The names of these types are of the form
Integer_n
for the signed types, andUnsigned_n
for the modular types;- For example, for a typical 32-bit machine the corresponding types might be
Integer_8
,Unsigned_8
,Integer_16
,Unsigned_16
,Integer_32
, andUnsigned_32
.
- For example, for a typical 32-bit machine the corresponding types might be
- For each such modular type in
Interfaces
, shifting and rotating subprograms as specified in the declaration ofInterfaces
above. These subprograms are Intrinsic. They operate on a bit-by-bit basis, using the binary representation of the value of the operands to yield a binary representation for the result. TheAmount
parameter gives the number of bits by which to shift or rotate. For shifting, zero bits are shifted in, except in the case ofShift_Right_Arithmetic
, where one bits are shifted in ifValue
is at least half the modulus. - Floating point types corresponding to each floating point format fully supported by the hardware.
- The names for these floating point types are not specified. However, if IEEE arithmetic is supported, then the
names should be
IEEE_Float_32
andIEEE_Float_64
for single and double precision, respectively.
- The names for these floating point types are not specified. However, if IEEE arithmetic is supported, then the
names should be
Shifting and Rotating
“Shifting” and “rotating” have the conventional meaning. Neither of these terms is usefully defined by the usual normative references of the Reference Manual, so we provide pseudo-code here to describe the intended semantics of the above wording (all operations in these examples are using modular semantics).
function Rotate_Left(Value: Unsigned_n; Amount: Natural) return Unsigned_n is
Result: Unsigned_n := Value;
Bit : Unsigned_n range 0 .. 1;
begin
for Count in 1 .. Amount loop
Bit := Result/2**(n - 1); -- High-bit of Result
Result := Result*2 + Bit;
end loop;
return Result;
end Rotate_Left;
function Rotate_Right(Value: Unsigned_n; Amount: Natural) return Unsigned_n is
Result: Unsigned_n := Value;
Bit : Unsigned_n range 0 .. 1;
begin
for Count in 1 .. Amount loop
Bit := Result mod 2; -- Low-bit of Result
Result := Result/2 + (Bit * 2**(n - 1));
end loop;
return Result;
end Rotate_Right;
function Shift_Left(Value: Unsigned_n; Amount: Natural) return Unsigned_n is
Result: Unsigned_n := Value;
begin
for Count in 1 .. Amount loop
Result := Result * 2;
end loop;
return Result;
end Shift_Left;
function Shift_Right(Value: Unsigned_n; Amount: Natural) return Unsigned_n is
Result: Unsigned_n := Value;
begin
for Count in 1 .. Amount loop
Result := Result / 2;
end loop;
return Result;
end Shift_Right;
function Shift_Right_Arithmetic(Value: Unsigned_n; Amount: Natural) return Unsigned_n is
Result: Unsigned_n := Value;
Neg : constant Boolean := Result/2**(n-1) = 1; -- High-bit of Result
begin
for Count in 1 .. Amount loop
if Neg then
Result := Result/2 + 2**(n - 1);
else
Result := Result/2;
end if;
end loop;
return Result;
end Shift_Right_Arithmetic;
C#
See Also
The facilities relevant to interfacing with the C language and the corresponding subset of the C++ language are the
package Interfaces.C
and its children, and support for specifying the Convention
aspect with
convention_identifiers C, C_Pass_By_Copy
, and any of the C_Variadic_n
conventions.
The identifiers C_Variadic_0
, C_Variadic_1
, C_Variadic_2
, and so on are convention_identifiers.
These conventions are said to be C_Variadic
. The convention C_Variadic_n
is the calling convention for a
variadic C function taking n fixed parameters and then a variable number of additional parameters. The
C_Variadic_n
convention shall only be specified as the convention aspect for a subprogram, or for an
access-to-subprogram type, having at least n parameters. A type is compatible with a C_Variadic
convention if
and only if the type is C-compatible.
The package Interfaces.C
contains the basic types, constants, and subprograms that allow an Ada program to pass
scalars and strings to C and C++ functions. When this subclause mentions a C entity, the reference also applies to the
corresponding entity in C++.
package Interfaces.C
with pragma Pure is
-- Declarations based on C's <limits.h>
CHAR_BIT : constant := <implementation-defined>; -- typically 8
SCHAR_MIN: constant := <implementation-defined>; -- typically –128
SCHAR_MAX: constant := <implementation-defined>; -- typically 127
UCHAR_MAX: constant := <implementation-defined>; -- typically 255
-- Signed and Unsigned Integers
type int is range <implementation-defined>;
type short is range <implementation-defined>;
type long is range <implementation-defined>;
type signed_char is range SCHAR_MIN .. SCHAR_MAX;
for signed_char'Size use CHAR_BIT;
type unsigned is mod <implementation-defined>;
type unsigned_short is mod <implementation-defined>;
type unsigned_long is mod <implementation-defined>;
type unsigned_char is mod (UCHAR_MAX + 1);
for unsigned_char'Size use CHAR_BIT;
subtype plain_char is <implementation-defined>;
type ptrdiff_t is range <implementation-defined>;
type size_t is mod <implementation-defined>;
type C_bool is new Boolean;
-- Floating Point
type C_float is digits <implementation-defined>;
type double is digits <implementation-defined>;
type long_double is digits <implementation-defined>;
-- Characters and Strings
type char is <implementation-defined character type>;
nul: constant char := <implementation-defined>;
function To_C (Item: Character) return char;
function To_Ada(Item: char) return Character;
type char_array is array(size_t range <>) of aliased char
with Pack;
for char_array'Component_Size use CHAR_BIT;
function Is_Nul_Terminated(Item: char_array) return Boolean;
function To_C(Item: String; Append_Nul: Boolean := True) return char_array;
function To_Ada(Item: char_array; Trim_Nul: Boolean := True) return String;
procedure To_C (Item: String ; Target: out char_array; Count: out size_t ; Append_Nul: Boolean := True);
procedure To_Ada(Item: char_array; Target: out String ; Count: out Natural; Trim_Nul : Boolean := True);
-- Wide Character and Wide String
type wchar_t is <implementation-defined character type>;
wide_nul: constant wchar_t := <implementation-defined>;
function To_C (Item: Wide_Character) return wchar_t;
function To_Ada(Item: wchar_t) return Wide_Character;
type wchar_array is array(size_t range <>) of aliased wchar_t
with Pack;
function Is_Nul_Terminated(Item: wchar_array) return Boolean;
function To_C (Item: Wide_String; Append_Nul: Boolean := True) return wchar_array;
function To_Ada(Item: wchar_array; Trim_Nul : Boolean := True) return Wide_String;
procedure To_C (Item: Wide_String; Target: out wchar_array; Count: out size_t ; Append_Nul: Boolean := True);
procedure To_Ada(Item: wchar_array; Target: out Wide_String; Count: out Natural; Trim_Nul : Boolean := True);
-- ISO/IEC 10646 compatible types
type char16_t is <implementation-defined character type>;
char16_nul: constant char16_t := <implementation-defined>;
function To_C (Item: Wide_Character) return char16_t;
function To_Ada(Item: char16_t) return Wide_Character;
type char16_array is array(size_t range <>) of aliased char16_t
with Pack;
function Is_Nul_Terminated(Item: char16_array) return Boolean;
function To_C (Item: Wide_String ; Append_Nul: Boolean := True) return char16_array;
function To_Ada(Item: char16_array; Trim_Nul : Boolean := True) return Wide_String;
procedure To_C (Item: Wide_String ; Target: out char16_array; Count: out size_t ; Append_Nul: Boolean := True);
procedure To_Ada(Item: char16_array; Target: out Wide_String ; Count: out Natural; Trim_Nul : Boolean := True);
type char32_t is <implementation-defined character type>;
char32_nul: constant char32_t := <implementation-defined>;
function To_C (Item: Wide_Wide_Character) return char32_t;
function To_Ada(Item: char32_t) return Wide_Wide_Character;
type char32_array is array(size_t range <>) of aliased char32_t
with Pack;
function Is_Nul_Terminated(Item: char32_array) return Boolean;
function To_C (Item: Wide_Wide_String; Append_Nul: Boolean := True) return char32_array;
function To_Ada(Item: char32_array ; Trim_Nul : Boolean := True) return Wide_Wide_String;
procedure To_C (Item: Wide_Wide_String; Target: out char32_array ; Count: out size_t ; Append_Nul: Boolean := True);
procedure To_Ada(Item: char32_array ; Target: out Wide_Wide_String; Count: out Natural; Trim_Nul : Boolean := True);
Terminator_Error: exception;
end Interfaces.C;
- An Ada procedure corresponds to a void-returning C function.
- The programmer can also choose an Ada procedure when the C function returns an
int
that is to be discarded. - An Ada enumeration type corresponds to a C enumeration type with corresponding enumeration literals having the same
internal codes, provided the internal codes fall within the range of the C
int
type. - An Ada
in
scalar parameter is passed as a scalar argument to a C function. - An Ada
in
parameter of an access-to-object type with designated typeT
is passed as at*
argument to a C function, wheret
is the C type corresponding to the Ada typeT
. - An Ada
access T
parameter, or an Adaout
orin out
parameter of an elementary typeT
, is passed as at*
argument to a C function, wheret
is the C type corresponding to the Ada typeT
. In the case of an elementaryout
orin out
parameter, a pointer to a temporary copy is used to preserve by-copy semantics. - An Ada parameter of a (record) type
T
of conventionC_Pass_By_Copy
, of modein
, is passed as at
argument to a C function, wheret
is the C struct corresponding to the Ada typeT
. - An Ada parameter of a record type
T
, other than an in parameter of a type of conventionC_Pass_By_Copy
, is passed as at*
argument to a C function, with theconst
modifier if the Ada mode isin
, wheret
is the C struct corresponding to the Ada typeT
. - An Ada parameter of an array type with component type
T
, is passed as at*
argument to a C function, with the const modifier if the Ada mode isin
, wheret
is the C type corresponding to the Ada typeT
. - An Ada parameter of an access-to-subprogram type is passed as a pointer to a C function whose prototype corresponds to the designated subprogram’s specification.
- An Ada parameter of a private type is passed as specified for the full view of the type.
- The rules of correspondence given above for parameters of mode
in
also apply to the return object of a function. - An implementation should provide
unsigned_long_long
andlong_long
as 64-bit modular and signed integer types (respectively) in packageInterfaces.C
if the C implementation supportsunsigned long long
andlong long
as 64-bit types.
sizeof
To obtain the effect of C’s sizeof(item_type)
, where Item_Type
is the corresponding Ada type, evaluate
the expression: size_t(Item_Type'Size/CHAR_BIT)
.
Variadic Functions
A variadic C function can correspond to several Ada subprograms, taking various specific numbers and types of parameters.
NULL Termination
Values of type char_array
are not implicitly terminated with nul
. If a char_array
is to be
passed as a parameter to an imported C function requiring nul
termination, it is the programmer’s
responsibility to obtain this effect.
Example Using Interfaces.C
with Interfaces.C;
procedure Test is
package C renames Interfaces.C;
use type C.char_array;
-- Call <string.h> strcpy:
-- char* strcpy(char* s1, const char* s2);
-- Note: since the C function's return value is of no interest, the Ada interface is a procedure
procedure Strcpy(Target: out C.char_array; Source: C.char_array)
with Import => True, Convention => C, External_Name => "strcpy";
-- Call <sdtio.h> printf:
-- int printf(const char* format, ...);
-- This function writes the C string pointed by format to the standard output (stdout).
-- If format includes format specifiers (subsequences beginning with %), the additional
-- arguments following format are formatted and inserted in the resulting string
-- replacing their respective specifiers. If the number of arguments does not match
-- the number of format specifiers, or if the types of the arguments do not match
-- the corresponding format specifier, the behaviour is undefined. On success, the
-- printf function returns the total number of characters written to the standard output.
-- If a writing error occurs, a negative number is returned.
-- Note: since the C function's return value is of no interest, the Ada interface is a procedure
procedure Printf(Format: C.char_array; Param1: C.char_array; Param2: C.int)
with Import => True, Convention => C_Variadic_1, External_Name => "printf";
Chars1: C.char_array(1 .. 20);
Chars2: C.char_array(1 .. 20);
begin
Chars2(1 .. 6) := "qwert" & C.nul;
Strcpy(Chars1, Chars2);
-- Now Chars1(1 .. 6) = "qwert" & C.Nul
Printf("The String=%s, Length=%d", Chars1, Chars1'Length);
end Test;
C Strings#
The package Interfaces.C.Strings
declares types and subprograms allowing an Ada program to allocate, reference,
update, and free C-style strings. In particular, the private type chars_ptr
corresponds to a common use of
char *
in C programs, and an object of this type can be passed to a subprogram to which with
Import => True, Convention => C
has been specified, and for which char *
is the type of the argument of
the C function.
package Interfaces.C.Strings
with Preelaborate, Nonblocking, Global => in out synchronized is
type char_array_access is access all char_array;
type chars_ptr is private
with Preelaborable_Initialization;
type chars_ptr_array is array(size_t range <>) of aliased chars_ptr;
Null_Ptr: constant chars_ptr;
function To_Chars_Ptr(Item: char_array_access; Nul_Check: Boolean := False) return chars_ptr;
function New_Char_Array(Chars: char_array) return chars_ptr;
function New_String(Str: String) return chars_ptr;
procedure Free(Item: in out chars_ptr);
Dereference_Error: exception;
function Value(Item: chars_ptr) return char_array;
function Value(Item: chars_ptr; Length: size_t) return char_array;
function Value(Item: chars_ptr) return String;
function Value(Item: chars_ptr; Length: size_t) return String;
function Strlen(Item: chars_ptr) return size_t;
procedure Update(Item: chars_ptr; Offset: size_t; Chars: char_array; Check: Boolean := True);
procedure Update(Item: chars_ptr; Offset: size_t; Str : String ; Check: Boolean := True);
Update_Error: exception;
end Interfaces.C.Strings;
Erroneous Execution
Execution of any of the following is erroneous if the Item
parameter is not null_ptr
and Item
does not point to a nul
-terminated array of char
s:
- A
Value
function not taking aLength
parameter - The
Free
procedure - The
Strlen
function
Execution of Free(X)
is also erroneous if the chars_ptr
X
was not returned by
New_Char_Array
or New_String
.
Reading or updating a freed char_array
is erroneous.
Execution of Update
is erroneous if Check
is False
and a call with Check
equal to
True
would have propagated Update_Error
.
C Pointers#
The generic package Interfaces.C.Pointers
allows the Ada programmer to perform C-style operations on pointers.
It includes an access type Pointer
, Value
functions that dereference a Pointer
and deliver the
designated array, several pointer arithmetic operations, and “copy” procedures that copy the contents of a source
pointer into the array designated by a destination pointer. As in C, it treats an object Ptr
of type
Pointer
as a pointer to the first element of an array, so that for example, adding 1 to Ptr
yields a
pointer to the second element of the array.
The generic allows two styles of usage: one in which the array is terminated by a special terminator element; and another in which the programmer keeps track of the length.
generic
type Index is (<>);
type Element is private;
type Element_Array is array(Index range <>) of aliased Element;
Default_Terminator: Element;
package Interfaces.C.Pointers
with Preelaborate, Nonblocking, Global => in out synchronized is
type Pointer is access all Element;
function Value(Ref: Pointer; Terminator: Element := Default_Terminator) return Element_Array;
function Value(Ref: Pointer; Length: ptrdiff_t) return Element_Array;
Pointer_Error: exception;
-- C-style Pointer arithmetic
function "+"(Left: Pointer; Right: ptrdiff_t) return Pointer with Convention => Intrinsic;
function "+"(Left: ptrdiff_t; Right: Pointer) return Pointer with Convention => Intrinsic;
function "-"(Left: Pointer; Right: ptrdiff_t) return Pointer with Convention => Intrinsic;
function "-"(Left: Pointer; Right: Pointer) return ptrdiff_t with Convention => Intrinsic;
procedure Increment(Ref: in out Pointer) with Convention => Intrinsic;
procedure Decrement(Ref: in out Pointer) with Convention => Intrinsic;
function Virtual_Length(Ref: Pointer; Terminator: Element := Default_Terminator) return ptrdiff_t;
procedure Copy_Terminated_Array(Source : Pointer;
Target : Pointer;
Limit : ptrdiff_t := ptrdiff_t'Last;
Terminator: Element := Default_Terminator);
procedure Copy_Array(Source: Pointer; Target: Pointer; Length: ptrdiff_t);
end Interfaces.C.Pointers;
Erroneous Execution
It is erroneous to dereference a Pointer
that does not designate an aliased Element
.
Execution of Value(Ref, Terminator)
is erroneous if Ref
does not designate an aliased Element
in an Element_Array
terminated by Terminator
.
Execution of Value(Ref, Length)
is erroneous if Ref
does not designate an aliased Element
in
an Element_Array
containing at least Length
Element
s between the designated Element
and the end of the array, inclusive.
Execution of Virtual_Length(Ref, Terminator)
is erroneous if Ref
does not designate an aliased
Element
in an Element_Array
terminated by Terminator
.
Execution of Copy_Terminated_Array(Source, Target, Limit, Terminator)
is erroneous in either of the
following situations:
- Execution of both
Value(Source, Terminator)
andValue(Source, Limit)
are erroneous, or - Copying writes past the end of the array containing the
Element
designated byTarget
.
Execution of Copy_Array(Source, Target, Length)
is erroneous if either Value(Source, Length)
is
erroneous, or copying writes past the end of the array containing the Element
designated by Target
.
To compose a Pointer
from an Element_Array
, use 'Access
on the first element. For example
(assuming appropriate instantiations):
Some_Array : Element_Array(0 .. 5);
Some_Pointer: Pointer := Some_Array(0)'Access;
Examples of Using Interfaces.C.Pointers
with Interfaces.C.Pointers;
with Interfaces.C.Strings;
procedure Test_Pointers is
package C renames Interfaces.C;
package Char_Ptrs is new C.Pointers(Index => C.size_t,
Element => C.char,
Element_Array => C.char_array,
Default_Terminator => C.nul);
use type Char_Ptrs.Pointer;
subtype Char_Star is Char_Ptrs.Pointer;
procedure Strcpy(Target_Ptr, Source_Ptr: Char_Star) is
Target_Temp_Ptr: Char_Star := Target_Ptr;
Source_Temp_Ptr: Char_Star := Source_Ptr;
Element : C.char;
begin
if Target_Temp_Ptr = null or Source_Temp_Ptr = null then
raise C.Strings.Dereference_Error;
end if;
loop
Element := Source_Temp_Ptr.all;
Target_Temp_Ptr.all := Element;
exit when C."="(Element, C.nul);
Char_Ptrs.Increment(Target_Temp_Ptr);
Char_Ptrs.Increment(Source_Temp_Ptr);
end loop;
end Strcpy;
begin
...
end Test_Pointers;
Unchecked Unions#
Specifying aspect Unchecked_Union
to have the value True
defines an interface correspondence between a
given discriminated type and some C union. The aspect requires that the associated type shall be given a representation
that allocates no space for its discriminant(s).
type T(Flag: Boolean := False) is record
case Flag is
when False => F1: Float := 0.0;
when True => F2: Integer := 0;
end case;
end record with Unchecked_Union;
X: T;
Y: Integer := X.F2; -- erroneous
COBOL#
The facilities relevant to interfacing with the COBOL language are the package Interfaces.COBOL
and support for
specifying the Convention
aspect with convention_identifier COBOL
.
The COBOL interface package supplies several sets of facilities:
- A set of types corresponding to the native COBOL types of the supported COBOL implementation (so-called “internal COBOL representations”), allowing Ada data to be passed as parameters to COBOL programs
- A set of types and constants reflecting external data representations such as can might be found in files or databases, allowing COBOL-generated data to be read by an Ada program, and Ada-generated data to be read by COBOL programs
- A generic package for converting between an Ada decimal type value and either an internal or external COBOL
representation
package Interfaces.COBOL with Preelaborate, Nonblocking, Global => in out synchronized is -- Types and operations for internal data representations type Floating is digits <implementation-defined>; type Long_Floating is digits <implementation-defined>; type Binary is range <implementation-defined>; type Long_Binary is range <implementation-defined>; Max_Digits_Binary : constant := <implementation-defined>; Max_Digits_Long_Binary: constant := <implementation-defined>; type Decimal_Element is mod <implementation-defined>; type Packed_Decimal is array(Positive range <>) of Decimal_Element with Pack; type COBOL_Character is <implementation-defined character type>; Ada_To_COBOL: array(Character) of COBOL_Character := <implementation-defined>; COBOL_To_Ada: array(COBOL_Character) of Character := <implementation-defined>; type Alphanumeric is array(Positive range <>) of COBOL_Character with Pack; function To_COBOL(Item: String) return Alphanumeric; function To_Ada (Item: Alphanumeric) return String; procedure To_COBOL(Item: String ; Target: out Alphanumeric; Last: out Natural); procedure To_Ada (Item: Alphanumeric; Target: out String ; Last: out Natural); type Numeric is array(Positive range <>) of COBOL_Character with Pack; -- Formats for COBOL data representations type Display_Format is private; Unsigned : constant Display_Format; Leading_Separate : constant Display_Format; Trailing_Separate : constant Display_Format; Leading_Nonseparate : constant Display_Format; Trailing_Nonseparate: constant Display_Format; type Binary_Format is private; High_Order_First: constant Binary_Format; Low_Order_First : constant Binary_Format; Native_Binary : constant Binary_Format; type Packed_Format is private; Packed_Unsigned: constant Packed_Format; Packed_Signed : constant Packed_Format; -- Types for external representation of COBOL binary data type Byte is mod 2**COBOL_Character'Size; type Byte_Array is array(Positive range <>) of Byte with Pack; Conversion_Error: exception; generic type Num is delta <> digits <>; package Decimal_Conversions is -- Display Formats: data values are represented as Numeric function Valid (Item: Numeric; Format: Display_Format) return Boolean; function Length( Format: Display_Format) return Natural; function To_Decimal(Item: Numeric; Format: Display_Format) return Num; function To_Display(Item: Num ; Format: Display_Format) return Numeric; -- Packed Formats: data values are represented as Packed_Decimal function Valid (Item: Packed_Decimal; Format: Packed_Format) return Boolean; function Length( Format: Packed_Format) return Natural; function To_Decimal(Item: Packed_Decimal; Format: Packed_Format) return Num; function To_Packed (Item: Num ; Format: Packed_Format) return Packed_Decimal; -- Binary Formats: external data values are represented as Byte_Array function Valid (Item: Byte_Array; Format: Binary_Format) return Boolean; function Length( Format: Binary_Format) return Natural; function To_Decimal(Item: Byte_Array; Format: Binary_Format) return Num; function To_Binary (Item: Num ; Format: Binary_Format) return Byte_Array; -- Internal Binary formats: data values are of type Binary or Long_Binary function To_Decimal(Item: Binary) return Num; function To_Decimal(Item: Long_Binary) return Num; function To_Binary (Item: Num) return Binary; function To_Long_Binary(Item: Num) return Long_Binary; end Decimal_Conversions; end Interfaces.COBOL;
Examples of Interfaces.COBOL
with Interfaces.COBOL;
procedure Test_Call is
-- Assume that a COBOL program PROG has the following declaration
-- in its LINKAGE section:
-- 01 Parameter-Area
-- 05 NAME PIC X(20).
-- 05 SSN PIC X(9).
-- 05 SALARY PIC 99999V99 USAGE COMP.
-- The effect of PROG is to update SALARY based on some algorithm
package COBOL renames Interfaces.COBOL;
type Salary_Type is delta 0.01 digits 7;
type COBOL_Record is record
Name : COBOL.Numeric(1 .. 20);
SSN : COBOL.Numeric(1 .. 9);
Salary: COBOL.Binary; -- Assume Binary = 32 bits
end record with Convention => COBOL;
procedure Prog(Item: in out COBOL_Record)
with Import => True, Convention => COBOL;
package Salary_Conversions is new COBOL.Decimal_Conversions(Salary_Type);
Some_Salary: Salary_Type := 12_345.67;
Some_Record: COBOL_Record := (Name => "Johnson, John ",
SSN => "111223333",
Salary => Salary_Conversions.To_Binary(Some_Salary));
begin
Prog(Some_Record);
...
end Test_Call;
with Interfaces.COBOL;
with COBOL_Sequential_IO; -- Assumed to be supplied by implementation
procedure Test_External_Formats is
-- Assume that a COBOL program has created a sequential file with
-- the following record structure, and that we want
-- process the records in an Ada program
-- 01 EMPLOYEE-RECORD
-- 05 NAME PIC X(20).
-- 05 SSN PIC X(9).
-- 05 SALARY PIC 99999V99 USAGE COMP.
-- 05 ADJUST PIC S999V999 SIGN LEADING SEPARATE.
-- The COMP data is binary (32 bits), high-order byte first
package COBOL renames Interfaces.COBOL;
type Salary_Type is delta 0.01 digits 7;
type Adjustments_Type is delta 0.001 digits 6;
type COBOL_Employee_Record_Type is record -- External representation
Name : COBOL.Alphanumeric(1 .. 20);
SSN : COBOL.Alphanumeric(1 .. 9);
Salary: COBOL.Byte_Array(1 .. 4);
Adjust: COBOL.Numeric(1 .. 7); -- Sign and 6 digits
end record with Convention => COBOL;
package COBOL_Employee_IO is new COBOL_Sequential_IO(COBOL_Employee_Record_Type);
use COBOL_Employee_IO;
COBOL_File: File_Type;
type Ada_Employee_Record_Type is record -- Internal representation
Name : String(1 .. 20);
SSN : String(1 .. 9);
Salary: Salary_Type;
Adjust: Adjustments_Type;
end record;
COBOL_Record: COBOL_Employee_Record_Type;
Ada_Record : Ada_Employee_Record_Type;
package Salary_Conversions is new COBOL.Decimal_Conversions(Salary_Type);
use Salary_Conversions;
package Adjustments_Conversions is new COBOL.Decimal_Conversions(Adjustments_Type);
use Adjustments_Conversions;
begin
Open(COBOL_File, Name => "Some_File");
loop
Read(COBOL_File, COBOL_Record);
Ada_Record.Name := COBOL.To_Ada(COBOL_Record.Name);
Ada_Record.SSN := COBOL.To_Ada(COBOL_Record.SSN);
Ada_Record.Salary := To_Decimal(COBOL_Record.Salary, COBOL.High_Order_First);
Ada_Record.Adjust := To_Decimal(COBOL_Record.Adjust, COBOL.Leading_Separate);
... -- Process Ada_Record
end loop;
exception
when End_Error => ...
end Test_External_Formats;
Fortran#
The facilities relevant to interfacing with the Fortran language are the package Interfaces.Fortran
and support
for specifying the Convention
aspect with convention_identifier Fortran
.
The package Interfaces.Fortran
defines Ada types whose representations are identical to the default
representations of the Fortran intrinsic types Integer
, Real
, Double Precision
, Complex
,
Logical
, and Character
in a supported Fortran implementation. These Ada types can therefore be used to
pass objects between Ada and Fortran programs.
with Ada.Numerics.Generic_Complex_Types;
pragma Elaborate_All(Ada.Numerics.Generic_Complex_Types);
package Interfaces.Fortran
with pragma Pure is
type Fortran_Integer is range <implementation-defined>;
type Real is digits <implementation-defined>;
type Double_Precision is digits <implementation-defined>;
type Logical is new Boolean;
package Single_Precision_Complex_Types is new Ada.Numerics.Generic_Complex_Types(Real);
type Complex is new Single_Precision_Complex_Types.Complex;
subtype Imaginary is Single_Precision_Complex_Types.Imaginary;
i: Imaginary renames Single_Precision_Complex_Types.i;
j: Imaginary renames Single_Precision_Complex_Types.j;
package Double_Precision_Complex_Types is new Ada.Numerics.Generic_Complex_Types(Double_Precision);
type Double_Complex is new Double_Precision_Complex_Types.Complex;
subtype Double_Imaginary is Double_Precision_Complex_Types.Imaginary;
type Character_Set is <implementation-defined character type>;
type Fortran_Character is array(Positive range <>) of Character_Set
with Pack;
function To_Fortran(Item: Character) return Character_Set;
function To_Ada (Item: Character_Set) return Character;
function To_Fortran(Item: String) return Fortran_Character;
function To_Ada (Item: Fortran_Character) return String;
procedure To_Fortran(Item: String ; Target: out Fortran_Character; Last: out Natural);
procedure To_Ada (Item: Fortran_Character; Target: out String ; Last: out Natural);
end Interfaces.Fortran;
Interfaces.Fortran
with Interfaces.Fortran; use Interfaces.Fortran;
procedure Ada_Application is
type Fortran_Matrix is array(Fortran_Integer range <>, Fortran_Integer range <>) of Double_Precision
with Convention => Fortran; -- stored in Fortran's column-major order
procedure Invert(Rank: Fortran_Integer; X: in out Fortran_Matrix)
with Import => True, Convention => Fortran; -- a Fortran subroutine
Rank : constant Fortran_Integer := 100;
My_Matrix: Fortran_Matrix (1 .. Rank, 1 .. Rank);
Precision: constant := 6;
type Standard_Deviation is digits Precision
with Convention => Fortran;
Deviation: Standard_Deviation;
-- Declarations to match the following Fortran declarations:
-- integer, parameter :: precision = selected_real_kind(p=6)
-- real(precision) :: deviation
begin
...
My_Matrix := ...;
...
Invert(Rank, My_Matrix);
...
Deviation := ...;
...
end Ada_Application;