2012-04-16 32 views
6

Ich versuche ein C-Makro von Vala zu verwenden. Es scheint mir, dass dies mit der CCode-Direktive möglich sein sollte, aber ich finde keine sinnvolle Dokumentation darüber, wie man sie benutzt.Wie verwende ich CCode-Attribute in Vala?

Es gibt einen kurzen Abschnitt über CCode-Argumente in "The Hacker's Guide to Vala" und mailing list thread about calling a C macro from Vala with CCode.

Aber keine Ressource hilft mir wirklich zu verstehen, was CCode wirklich tut. Offensichtlich beeinflusst es, wie Vala C-Code generiert, aus der Hackers' Guide to Vala kann ich folgern, dass die CCode-Direktive wahrscheinlich direkten Einfluss darauf hat, wie der CCode-Baum beim Durchqueren von Valas AST erstellt wird.

Kann jemand etwas mehr erklären, was CCode tut?

+1

Ich fand mehr Dokumentation: https://live.gnome.org/Vala/Manual/Attributes#CCode_Attribute –

Antwort

8

Leider gibt es nicht viel Dokumentation über CCode, die allein sinnvoll ist. Was Sie tun müssen, ist es in Verbindung mit den VAPI-Dateien, die mit Vala geliefert werden. Im Grunde, dass Sie wahrscheinlich Ihr Makro etwas wie folgt verwenden:

[CCode(cname = "FOO", cheader_filename = "blah.h")] 
public extern void foo(); 

Hier setzen wir die cname (dh der Name, der in den C-Code wird ausgegeben), und die cheader_filename (dh die Header-Datei, die #include sein sollte d). Die meisten anderen CCode-Attribute steuern, wie Arrays gehandhabt werden. array_length = false zeigt an, dass ein Array von unbekannter Länge ist. Dies kann auf einen Parameter oder auf die Methode angewendet werden, um anzuzeigen, dass dies für den Rückgabetyp gilt. Zum Beispiel:

[CCode(array_length = false)] public int[] x(); 
[CCode(array_null_terminated = true)] public FileStream[] y(); 
public int[] z(); 

In diesem Beispiel wird x unbekannte Feldlänge haben und einen erwarteten C Prototyp int *x(void) haben, während y angenommen wird, einen Null-terminierte Array mit dem erwarteten C-Prototyp von FILE **y(void) haben. Schließlich wird z angenommen eine Arraylänge out-Parameter haben (dh einen Prototyp int *z(int *length), wo length ist ein Zeiger auf, wobei die Länge der zurückgegebenen Array zu speichern.

Alle diese Faktoren können auch auf Parameter angewendet werden. Es ist auch nützlich, array_length_pos anzugeben, wenn es eine Array-Länge gibt, aber nicht das Argument unmittelbar nach dem Array.Wenn ein Parameter ein Delegat ist, gibt target_pos an, wo die Benutzerdaten übergeben werden (dh die void*, die mit dem Funktionszeiger geht) .

Es gibt auch eine Vielzahl von CCode-Attributen für Delegaten, Klassen und Strukturen instance_pos gibt an, wo Klassen-/Struct-Instanz oder Delegate Benutzerdaten geht. Alle Positionsargumente sind mit einer Gleitkommazahl angegeben. Dadurch können mehrere Positionen codiert werden. Zum Beispiel: Angenommen wir einen C Prototyp hatte:

void foo(void* userdata, int length, double *dbl_array, void(*handler)(double,void*)); 

dann könnten wir schreiben:

[CCode(cname = "foo")] 
public void foo([CCode(array_length_pos = 0.2)] double[] array, [CCode(target_pos = 0.1)] Handler func); 

Da Handler als Delegierter an anderer Stelle definiert ist, können Sie sehen, dass die pos Werte, die die Argumente nach Argument 0 (dh der Start) und dann in einer bestimmten Reihenfolge.

Klassen und Strukturen haben Funktionen zur Initialisierung, Zerstörung und Referenzzählung, aber diese sind ziemlich einfach. Handling Generika ist auch ein bisschen kompliziert. Auch hier sind die VAPIs die beste Quelle für Erkenntnisse.Dies reicht jedoch aus, um mit den grundlegenden C-Funktionen und Makros zu beginnen.