2012-04-16 6 views
6

Estoy tratando de usar una macro C de Vala. Me parece que esto debería ser posible con la directiva CCode, pero no puedo encontrar ninguna documentación significativa sobre cómo usarlo.¿Cómo uso los atributos de CCode en Vala?

Hay una breve sección sobre los argumentos de CCode en "The Hacker's Guide to Vala" y mailing list thread about calling a C macro from Vala with CCode.

Pero ninguno de los recursos realmente me ayuda a entender lo que realmente hace CCode. Obviamente afecta la forma en que Vala genera el código C, del Hackers' Guide to Vala, puedo deducir que la directiva CCode probablemente me da una influencia directa en cómo se crea el árbol CCode al atravesar Valas AST.

¿Alguien podría explicar un poco más lo que hace CCode?

+1

Encontré más documentación: https://live.gnome.org/Vala/Manual/Attributes#CCode_Attribute –

Respuesta

8

Desafortunadamente, no hay una gran cantidad de documentación sobre CCode que tenga sentido solo. Lo que necesita hacer es usarlo junto con los archivos VAPI que viene con Vala. En su forma más básica, es probable que use la macro algo como esto:

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

Aquí estamos estableciendo la cname (es decir, el nombre que se emitirá en el código C), y la cheader_filename (es decir, el archivo de encabezado que debe ser #include d). La mayoría de los otros atributos de CCode controlan cómo se manejan las matrices. array_length = false indica que una matriz es de longitud desconocida. Esto se puede aplicar a un parámetro o al método, lo que indica que se aplica al tipo de devolución. Por ejemplo:

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

En este ejemplo, x tendrá longitud de la matriz desconocido y tienen un prototipo C esperado de int *x(void), mientras y se supone que tiene una matriz terminada en nulo con el prototipo C esperado de FILE **y(void). Finalmente, z se supone que tiene una longitud de la matriz a cabo parámetro (es decir, un prototipo de int *z(int *length), donde length es un puntero a dónde almacenar la longitud de la matriz devuelta.

Todo esto puede aplicarse a los parámetros también. También es útil especificar array_length_pos si hay una longitud de matriz pero no es el argumento inmediatamente después de la matriz. Si un parámetro es un delegado, target_pos especifica dónde se pasan los datos del usuario (es decir, void* que va con el puntero de función)

También hay una variedad de atributos CCode para usar con delegados, clases y estructuras. instance_pos especifica dónde instancia de clase/struct o delegar datos de usuario va. Todos los argumentos de posición se especifican con un número de coma flotante. Esto permite codificar múltiples posiciones. Por ejemplo, supongamos que tenemos un prototipo C:

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

entonces podríamos escribir esto:

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

Dada Handler se define como un delegado en otro lugar, se puede ver que los pos valores ponen los argumentos después argumento 0 (es decir, el inicio) y luego en un orden particular.

Las clases y las estructuras tienen funciones para gestionar la inicialización, la destrucción y el recuento de referencias, pero son bastante sencillas. Manejar genéricos también es un poco complicado. Una vez más, los VAPI son la mejor fuente de información.Sin embargo, eso es suficiente para que comiences con tus funciones C básicas y tus macros.