如何在Vala中使用C代码属性?

6
我试图使用Vala的C宏。我觉得使用CCode指令应该是可能的,但我无法找到任何有意义的关于如何使用它的文档。 "The Hacker's Guide to Vala"中有一个关于CCode参数的简短部分,以及一个在邮件列表中讨论从Vala调用C宏的CCode
但是这两个资源都没有真正帮助我理解CCode做了什么。它显然会影响Vala生成的C代码。从Hackers' Guide to Vala中,我可以推断出,CCode指令可能会直接影响在遍历Vala AST时创建CCode树的方法。
有人能否更详细地解释一下CCode的功能?

1
我找到了更多的文档:https://live.gnome.org/Vala/Manual/Attributes#CCode_Attribute - Andreas Raster
1个回答

8

很遗憾,关于CCode的文档并不多,而且这些文档单独来看也不太容易理解。您需要将其与Vala附带的VAPI文件一起使用。最基本的用法可能是这样的:

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

这里我们设置了cname(即将被放入C代码中的名称)和cheader_filename(即应该被#include的头文件)。大部分其他的CCode属性控制如何处理数组。 array_length = false表示数组长度未知。这可以应用于参数或方法,表明它适用于返回类型。例如:
[CCode(array_length = false)] public int[] x();
[CCode(array_null_terminated = true)] public FileStream[] y();
public int[] z();

在这个示例中,x将具有未知的数组长度,其预期的C原型为int * x(void),而y则假定具有以null结尾的数组,其预期的C原型为FILE ** y(void)。最后,假设z具有一个数组长度输出参数(即,原型为int * z(int * length),其中length是指向存储返回的数组长度的位置的指针)。
所有这些也可以应用于参数。如果存在数组长度但它不是紧跟在数组后面的参数,则指定array_length_pos也很有用。如果参数是委托,则target_pos指定用户数据传递的位置(即,与函数指针一起使用的void*)。
还有一种用于委托、类和结构体的CCode属性。 instance_pos指定类/结构实例或委托用户数据的位置。所有位置参数都用浮点数指定。这允许编码多个位置。例如,假设我们有一个C原型:
void foo(void* userdata, int length, double *dbl_array, void(*handler)(double,void*));

然后我们可以写成这样:
[CCode(cname = "foo")]
public void foo([CCode(array_length_pos = 0.2)] double[] array, [CCode(target_pos = 0.1)] Handler func);

鉴于Handler在其他地方已被定义为委托,您可以看到pos值将参数放置在第一个参数(即开始)之后,并以特定顺序排列。

类和结构体具有处理初始化、销毁和引用计数的函数,但这些都相当简单。处理泛型也有点复杂。同样,VAPI是洞察力的最佳来源。然而,这已经足以让您开始使用基本的C函数和宏。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接