2012-04-16 70 views
6

我想从Vala使用C宏。在我看来,这应该是可能的CCode指令,但我没有找到任何有关如何使用它的有意义的文档。如何在Vala中使用CCode属性?

"The Hacker's Guide to Vala"mailing list thread about calling a C macro from Vala with CCode有一个关于CCode自变量的简短部分。

但无论是资源真的帮助我了解什么CCODE确实。它显然会影响Vala如何生成C代码,从Hackers' Guide to Vala我可以推断出CCode指令可能会直接影响到在遍历Valas AST时如何创建CCode树。

任何人可以解释多一点做什么CCODE?

+1

我发现了更多文档:https://live.gnome.org/Vala/Manual/Attributes#CCode_Attribute – 2012-04-16 14:12:01

回答

8

不幸的是,不是CCODE文档的大量单独有道理。您需要做的是将其与Vala附带的VAPI文件结合使用。在最基本的,你可能会使用你的宏是这样的:

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

这里我们设置cname(即,将被排放到C代码的名称),以及cheader_filename(即头文件应该是#include d)。大多数其他的CCode属性控制着数组的处理方式。 array_length = false表示数组长度未知。这可以应用于参数或方法,指示适用于返回类型。例如:

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

在这个例子中,x将具有未知阵列的长度和具有int *x(void)预期C原型,而假定y具有与FILE **y(void)预期C原型的空终止阵列。最后,假定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值将这些参数后,参数0(即开始),然后按特定顺序。

类和结构有函数来处理初始化,破坏和引用计数,但这些都是相当简单的。处理泛型也有点复杂。再次,VAPI是洞察力的最佳来源。但是,这足以让您开始使用基本的C函数和宏。