11. Anlage
 
zurück
11.2.2 Das C-Schnittstellenpaket


Da viele Anwendungen und Bibliotheksfunktionen in der Sprache C implementiert sind, ist es wichtig, daß Ada-95-Programme mit dieser Software kommunizieren können. Folgende generelle Regeln beschreiben, wie Ada- und C-Programme aufeinander abgebildet werden: • Eine Ada-Prozedur entspricht einer C-Funktion, die als "void" deklariert ist.
  • Eine Ada-Funktion entspricht einer C-Funktion, die nicht als "void" deklariert ist.
  • Einfache skalare Typen ("integer", "float" und "access") entsprechen den Typen von C.
  • Ein Verbund wird als Zeiger auf den Verbund übergeben;
  • Eine Reihung wird als Zeiger auf das erste Element der Reihung übergeben.bergeben;
  • Eine Reihung wird als Zeiger auf das erste Element der Reihung übergeben.
Das C-Schnittstellenpaket "Interfaces.C" unterstützt den Programmierer dabei, C-Funktionen nach Ada zu importieren und Ada-Unterprogramme nach C zu exportieren. Es enthält die Basistypen, Konstanten und Unterprogramme, die es einem Ada-Programm erlauben, Objekte eines skalaren Typs (Skalare Typen) und Zeichenketten an C-Funktionen zu übergeben. Die Kindpakete "Interfaces.C.Strings" und "Interfaces.C.Pointers" stellen spezielle Funktionen zum Umgang mit Zeichenketten und Zugriffstypen von C zur Verfügung.

Skalare Typen

Die vordefinierten C-Typen "int", "float" und "char" sind im Paket "Interfaces.C" deklariert und entsprechen den Typen der unterstützten Übersetzerimplementierung von C. Solange C-Parameter als Wert (copy in) übergeben werden, ist die Übergabe eines Skalars an eine C-Funktion einfach. Das Programm deklariert ein Unterprogramm in Ada mit den entsprechenden Parametern vom Modus "in".

Eine C-Funktion kann einen Parameter vom Typ "t*" besitzen, wobei t ein skalarer Wert ist und das rufende Unterprogramm eine Referenz an den skalaren Typ übergeben muß. Falls eine solche C-Funktion importiert werden soll, so muß das entsprechende Unterprogramm in Ada einen Parameter T vom Zugriffstyp (Möglichkeit 1) oder einen Parameter T vom Modus "in out" (Möglichkeit 2) deklarieren.

Bei der Parameterübergabe vom Modus "in out" (Möglichkeit 2) wird intern ein Zeiger auf eine temporäre Kopie des Parameters des Ada-Unterprogramms erzeugt, um die Kopiersemantik zu erreichen.

Zeichenketten

Das Paket "Interfaces.C" stellt einen implementierungsabhängigen Zeichentyp "char" zur Verfügung, der den Typ "char" in C nachbildet. Dieses kann oder kann nicht den Typ "character" in Ada entsprechen. Daher existieren zusätzliche Abbildungen zwischen den Typen "char" in C und
"character" in Ada.

Eine bedeutsame Anwendung des Pakets "Interfaces.C" ist die Komposition einer Zeichenkette in C und die Übergabe dieser an eine C-Funktion. Das Paket stellt hierfür verschiedene Möglichkeiten zur Verfügung.

Weitere Hilfen des Pakets "Interface.C" sind:
  • eine Konstante "Null_Ptr", die "(char*) null" entspricht.
  • eine Prozedur "Free", die "free()" in C entspricht.
  • eine Funktion "Value", der als Parameter ein Objekt vom Typ "chars_ptr" übergeben wird und die eine Zeichenkette in Ada als Ergebnis zurückgibt. Diese Funktion liefert die Ausnahme "dereference_error", falls ein "Null"-Zeiger übergeben wurde.
Die erste Möglichkeit der Übergabe einer Zeichenkette besteht darin, eine Zeichenkette in Ada zu deklarieren und diese für ein Objekt vom Typ "char_array" zu konvertieren. Viele C-Funktionen erwarten, daß Zeichenketten mit einem speziellen Endezeichen "nul" (in C als "\0" geschrieben) abschließen.

Da Zeichenketten in Ada normalerweise nicht mit einem Endezeichen abschließen, stellt das Paket "Interfaces.C" zwei Funktionen "To_C" und "To_Ada" zur Konvertierung einer Zeichenkette in Ada in eine Zeichenkette in C und umgekehrt zur Verfügung. Die mittels der Funktion "To_C" konvertierte Zeichenkette wird dann als aktueller Parameter an eine C-Funktion übergeben, die einen formalen Parameter vom Typ "char*" hat.

Eine zweite Möglichkeit besteht darin, daß aus einer Zeichenkette in Ada ein Objekt vom Typ "char"-Pointer in C generiert wird. Hierzu stellt das Kindpaket "Interfaces.C.Strings" einen privaten Typ "chars_ptr" zur Verfügung, der dem Typ "char*" in C entspricht. Mit Hilfe von zwei Allokatoren "New_Char_Array" bzw. "New_String" kann aus einer Zeichenkette in Ada dieser Zugriffstyp erzeugt werden.

Zugriffstypen

Das generische Paket "Interfaces.C.Pointers" erlaubt es, C-ähnliche Operationen auf Zugriffstypen auszuführen. Das Paket enthält einen Zugriffstyp "pointer", Wertfunktionen, die Objekte vom Typ "pointer" dereferenzieren, verschiedene arithmetische Operationen auf Objekte vom Typ "pointer" und Kopierprozeduren, die den Inhalt eines Ausgangsobjekt vom Typ "pointer" in eine Reihung, die durch das Zielobjekt vom Typ "pointer" bestimmt ist, kopiert. Wie in C wird ein Objekt Ptr vom Typ "pointer" als ein Zeiger auf das erste Element einer Reihung interpretiert. Das Resultat einer Addition des Wertes "1" zu Ptr liefert als Ergebnis das zweite Element der Reihung.

Das generische Paket kann auf zweierlei Art und Weise benutzt werden: im ersten Fall wird die Reihung mit einem Endeelement gekennzeichnet, im zweiten Fall muß der Programmierer selbst die Länge der Reihung bestimmen.


Verbunde

Falls eine C-Funktion einen Parameter vom Typ "struct*" erwartet, also einen Zeiger auf einen Verbund, so sollte ein entsprechendes Objekt vom Typ "record" deklariert und das Pragma "Convention" auf diesen Typ angewendet werden. Der Ada-Übersetzer wird eine Referenz zu
diesem deklarierten Verbund als Argument an die C-Funktion übergeben.

Nicht jeder Verbund kann von Ada als Parameter vom Typ "struct" an eine C-Funktion übergeben
werden. Es müssen nur C-ähnliche Verbundtypen T vom Pragma "Convention (C,T)" unterstützt
werden. Verbundtypen mit Diskriminanten oder Verbundtypen, deren Komponenten dynamisch
verändert werden können, brauchen vom Sprachstandard nicht unterstützt zu werden..n" nicht
unterstützt zu werden.

Beispiel:

with Interfaces.C;
procedure Test is
   package C renames Interfaces.C;
   use type C.char_array;
   -- Aufruf von strcpy:
   -- Definition von strcpy in C:
   -- char *strcpy(char *s1, const char *s2);
   -- Diese Funktion kopiert die Zeichenkette s2
   -- (einschließlich des terminierenden Null Characters) in das
   -- Array, worauf s1 zeigt. Falls die Kopieroperation zwischen
   -- Objekten stattfindet, die sich überlappen, ist die Operation
   -- undefiniert.
   -- Die Funktion strcp gibt als Wert s1 zurück.
   -- Bemerkung: Da der Rückgabewert der C-Funktion nicht von
   -- Interesse ist, ist die Ada-Schnittstelle eine Prozedur.

   procedure Strcpy(Target : out C.char_array;Source : in C.char_array);
   pragma Import(C, Strcpy, "strcpy");
   Erste_Zeichenkette : C.char_array(1 .. 20);
   Zweite_Zeichenkette : C.char_array(1 .. 20);
begin
   Zweite_Zeichenkette (1..6) := "qwert" & C.Nul;
   Strcpy(Erste_Zeichenkette, Zweite_Zeichenkette);
   -- Nun hat Erste_Zeichenkette (1..6) = "qwert" & C.Nul
end Test;



 
zurück
 Index   Ada Tour - Dokumentation  
© 2003 Förderverein Ada Deutschland e.V.