2012-04-16 10 views
6

Próbuję użyć makro C z Vala. Wydaje mi się, że powinno to być możliwe dzięki dyrektywie CCode, ale nie znalazłem żadnej znaczącej dokumentacji na temat tego, jak z niego korzystać.Jak używać atrybutów CCode w Vala?

Istnieje krótki rozdział dotyczący argumentów CCode w "The Hacker's Guide to Vala" i mailing list thread about calling a C macro from Vala with CCode.

Ale żaden zasób nie pomaga mi zrozumieć, co naprawdę robi CCOD. To oczywiście wpływa na to, jak Vala generuje kod C, z Hackers' Guide to Vala mogę wywnioskować, że dyrektywa CCode prawdopodobnie daje mi bezpośredni wpływ na to, jak drzewo CCode jest tworzone podczas przechodzenia Valas AST.

Czy ktokolwiek mógłby wyjaśnić nieco więcej, co robi CCode?

+1

Znalazłem więcej dokumentacji: https://live.gnome.org/Vala/Manual/Attributes#CCode_Attribute –

Odpowiedz

8

Niestety, nie ma zbyt wiele dokumentacji o CCode, która ma sens tylko w pojedynkę. To, co musisz zrobić, to używać go w połączeniu z plikami VAPI dostarczonymi z Vala. W jego najbardziej podstawowym, prawdopodobnie będziesz używać makro coś takiego:

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

Tutaj jesteśmy ustawienie cname (czyli nazwa, która będzie emitowana w kodzie C), a cheader_filename (tj plik nagłówkowy, który powinien być #include d). Większość innych atrybutów CCode kontroluje sposób obsługi tablic. array_length = false oznacza, że ​​tablica ma nieznaną długość. Można to zastosować do parametru lub metody, wskazując, że ma zastosowanie do typu zwracanego. Na przykład:

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

W tym przykładzie x będzie informacji o długości tablicy i mają spodziewaną prototypu C na int *x(void), a y zakłada się, że zerowy zakończony układ z oczekiwaną prototypu C FILE **y(void). Wreszcie z zakłada mieć długość tablicy z parametru (czyli prototyp int *z(int *length), gdzie length jest wskaźnik do miejsca przechowywania długość zwracanej tablicy.

Wszystkie te mogą być stosowane do parametrów też. Przydaje się również określenie array_length_pos, jeśli istnieje długość tablicy, ale nie jest to bezpośrednio po tablicy. Jeśli parametr jest delegatem, target_pos określa miejsce przekazania danych użytkownika (np. void*, który jest zgodny ze wskaźnikiem funkcji)

Istnieje również wiele różnych atrybutów CCode do użytku z delegatami, klasami i strukturami: instance_pos określa, gdzie wystąpi klasa/struktura lub deleguje dane użytkownika. Wszystkie argumenty pozycji są określane liczbą zmiennoprzecinkową. Pozwala to kodować wiele pozycji. Na przykład, załóżmy, że mieliśmy prototyp C:

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

wtedy możemy napisać tak:

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

Biorąc Handler jest zdefiniowany jako delegat gdzie indziej, można zobaczyć, że wartości pos umieścić argumenty po Argument 0 (tj. początek), a następnie w określonej kolejności.

Klasy i znaki strukturalne mają funkcje obsługi inicjowania, niszczenia i liczenia odwołań, ale są one dość proste. Obsługa leków generycznych jest również nieco skomplikowana. Ponownie, VAPI są najlepszym źródłem wglądu.Jednak wystarczy, aby zacząć od podstawowych funkcji C i makr.