Unfortunately, there is not much documentation in CCode that makes sense alone. What you need to do is use it along with the VAPI files that come with Vala. Basically, you'll probably use your macro something like this:
[CCode(cname = "FOO", cheader_filename = "blah.h")] public extern void foo();
Here we set cname
(that is, the name that will be selected in the C code), and cheader_filename
(i.e. the header file, which should be #include
d). Most other CCode attributes control the handling of arrays. array_length = false
indicates that the array has an unknown length. This can be applied to a parameter or method, indicating what applies to the return type. For instance:
[CCode(array_length = false)] public int[] x(); [CCode(array_null_terminated = true)] public FileStream[] y(); public int[] z();
In this example, x
will have an unknown array length and have the expected prototype C int *x(void)
, while it is assumed that y
has an array with zero completion with the expected prototype C FILE **y(void)
. Finally, it is assumed that z
has an array length parameter (i.e., the prototype int *z(int *length)
, where length
is a pointer to where to store the length of the returned array.
All of them can be applied to parameters. It is also useful to specify array_length_pos
if the length of the array exists, but this is not an argument immediately after the array. If the parameter is a delegate, target_pos
indicates where the user data is transferred (i.e. void*
, which goes with the function pointer).
There are also many CCode attributes for use with delegates, classes, and structures. instance_pos
indicates where the data of the instance of the class / structure or delegate goes. All position arguments are specified with a floating point number. This allows you to encode multiple items. For example, suppose we have a C prototype:
void foo(void* userdata, int length, double *dbl_array, void(*handler)(double,void*));
then we could write this:
[CCode(cname = "foo")] public void foo([CCode(array_length_pos = 0.2)] double[] array, [CCode(target_pos = 0.1)] Handler func);
This Handler
defined as a delegate elsewhere, you can see that the pos
values put the arguments after the 0 argument (i.e. the beginning), and then in a specific order.
Classes and structures have functions for handling initialization, destruction and reference counting, but they are pretty straightforward. Handling generics is also a bit complicated. Again, VAPI is the best source of understanding. However, this is enough to get started with basic C functions and macros.