# Ada Programming/Interfacing


## Interfacing

Ada is one of the few languages where interfacing is part of the
language standard. The programmer can interface with other programming
languages, or with the hardware.

## Other programming languages

The language standard defines the interfaces for
C, Cobol and
Fortran. Of course any implementation
might define further interfaces ---
GNAT for example defines an interface
to C++.

Interfacing with other languages is actually provided by pragma
Export,
Import and
Convention.

### Interfacing with C

The package Interfaces.C is used to define C types. C function wrappers
should be used to encapsulate types and functions on the C side. This
way the code is portable and foward-compatible. This is similar to the
way of interfacing with C in Java\'s JNI. Wrappers should be used for:

-   Translating typedefs defined in C includes to types defined in
    Interfaces.C;
-   Using macros and exposing macro values to the Ada side;
-   Using variable parameter list functions;
-   Defining multiple function wrappers for a function that takes weakly
    typed parameters such as a function that takes a char_array or a
    null pointer;
-   Using getters and setters for C structs that depend on operating
    system version or other compile-type aspect;
-   Using pointer arithmetic;
-   Keeping Ada source memory-safe.

#### Example

` Interfaces.C;`\
` System;`\
` Ada.Text_IO;`\
\
` Main `\
`   `` W32_Open_File_Dialog`\
`   `\
`      `` C `` Interfaces.C;`\
`      `` C;`\
`      `\
`      `` OPENFILENAME `` `` System.Address;`\
`      `` Window_Type `` `` System.Address;`\
`      `\
`      `` GetOpenFileName (p : OPENFILENAME) `` C.int;`\
`      `` Import (C, GetOpenFileName, "ada_getopenfilename");`\
`      `\
`      `` Allocate `` OPENFILENAME `\
`        Import => True,`\
`        Convention => C,`\
`        External_Name => "ofn_allocate";`\
`      `\
`      `` Set_Struct_Size (X : OPENFILENAME) `\
`        Import => True,`\
`        Convention => C,`\
`        External_Name => "ofn_set_struct_size";`\
`      `\
`      `` Set_Owner (X : OPENFILENAME; Owner : Window_Type) `\
`        Import => True,`\
`        Convention => C,`\
`        External_Name => "ofn_set_owner";`\
`      `\
`      `` Set_File (X : OPENFILENAME; File : char_array; Length : C.int) `\
`        Import => True,`\
`        Convention => C,`\
`        External_Name => "ofn_set_file";`\
`      `\
`      `` Set_Filter (X : OPENFILENAME; Filter : char_array);`\
`      `` Import (C, Set_Filter, "ofn_set_filter");`\
`      `\
`      `` Set_Filter_Index (X : OPENFILENAME; N : C.int) `\
`        Import => True,`\
`        Convention => C,`\
`        External_Name => "ofn_set_filter_index";`\
`      `\
`      `` Get_File (X : OPENFILENAME) `` System.Address;`\
`      `` Import (C, Get_File, "ofn_get_file");`\
`      `\
`      `` Get_File_Length (X : OPENFILENAME) `` C.size_t;`\
`      `` Import (C, Get_File_Length, "ofn_get_file_length");`\
`      `\
`      `` Free (X : OPENFILENAME) `\
`        Import => True,`\
`        Convention => C,`\
`        External_Name => "ofn_free";`\
`      `\
`      OFN : OPENFILENAME;`\
`      Ret : C.int;`\
`      File : `` C.char_array := "test.txt" & C.nul;`\
`      Filter : `` C.char_array := "All" & C.nul & "*.*" & C.nul & C.nul & C.nul;`\
`   `\
`      OFN := Allocate;`\
`      Set_Struct_Size (OFN);`\
`      Set_Owner (OFN, Window_Type (System.Null_Address));`\
`      Set_File (OFN, File, 256);`\
`      Set_Filter (OFN, Filter);`\
`      Set_Filter_Index (OFN, 0);`\
`      Ret := GetOpenFileName (OFN);`\
`      `` Ret = 0 `\
`         Free (OFN);`\
`         Ada.Text_IO.Put_Line ("No file selected.");`\
`         return;`\
`      `` ``;`\
`      `\
`         Selected_File_Address : System.Address := Get_File (OFN);`\
`         Selected_File_Length : C.size_t := Get_File_Length (OFN);`\
`         Selected_File : char_array (1 .. Selected_File_Length + 1);`\
`         `` Selected_File'Address `` Selected_File_Address;`\
`      `\
`         Ada.Text_IO.Put_Line (To_Ada (Selected_File, Trim_Nul => True));`\
`      ``;`\
`      Free (OFN);`\
`   `` W32_Open_File_Dialog;`\
\
`   W32_Open_File_Dialog;`\
` Main;`

``` c
#include <windows.h>
#include <stdlib.h>

OPENFILENAME *ofn_allocate()
{
    OPENFILENAME *ofn;
    ofn = (OPENFILENAME *) malloc(sizeof(OPENFILENAME));
    if (ofn == NULL)
        return NULL;
    memset(ofn, 0, sizeof(OPENFILENAME));
    return ofn;
}

void ofn_set_struct_size(OPENFILENAME *ofn)
{
    ofn->lStructSize = sizeof(OPENFILENAME);
}

void ofn_set_owner(OPENFILENAME *ofn, void *owner)
{
    ofn->hwndOwner = (HWND) owner;
}

void ofn_set_file(OPENFILENAME *ofn, char *file, int length)
{
    if (ofn->lpstrFile)
        free(ofn->lpstrFile);
    ofn->lpstrFile = (char *)malloc (length);
    if (ofn->lpstrFile == NULL) {
        ofn->nMaxFile = 0;
        return;
    }
    strncpy(ofn->lpstrFile, file, length);
    ofn->nMaxFile = length;
}

void ofn_set_filter(OPENFILENAME *ofn, char *filter)
{
    ofn->lpstrFilter = filter;
}

void ofn_set_filter_index(OPENFILENAME *ofn, int n)
{
    ofn->nFilterIndex = n;
}

void ofn_free(OPENFILENAME *ofn)
{
    if (ofn->lpstrFile)
        free(ofn->lpstrFile);
    free(ofn);
}

int ada_getopenfilename(OPENFILENAME *ofn)
{
    return (int) GetOpenFileNameA(ofn);
}

char *ofn_get_file(OPENFILENAME *ofn)
{
    return ofn->lpstrFile;
}

size_t ofn_get_file_length(OPENFILENAME *ofn)
{
    return (size_t) lstrlen (ofn->lpstrFile);
}
```

The following project file (getopenfilename.gpr) shows how to link to
comdlg32.dll:

    project Getopenfilename is
       for Languages use ("Ada", "C");
       for Source_Dirs use ("src");
       for Object_Dir use "obj";
       for Main use ("main.adb");

       package Linker is
          for Default_Switches ("ada") use ("-lComdlg32");
       end Linker;
    end Getopenfilename;

## Hardware devices

Embedded programmers usually have to write device drivers. Ada provides
extensive support for interfacing with hardware, like using
representation
clauses to specify
the exact representation of types used by the hardware, or standard
interrupt handling for writing Interrupt service
routines.

## See also

### Wikibook

-   Ada Programming
-   Ada
    Programming/Libraries/Interfaces

### Ada Reference Manual

-   
-   
### Ada 95 Rationale

-   
### Ada Quality and Style Guide

-   
Programming}}\|Interfacing Ada
Programming}}/Unfinished module\|Interfacing
