6

ValaのCマクロを使おうとしています。これはCCodeディレクティブで可能になるはずですが、使用方法に関する意味のあるドキュメントが見つかりません。

「TheHacker'sGuideto Vala」 には、CCode引数に関する簡単なセクションと、CCodeを使用してValaからCマクロを呼び出すことに関するメーリングリストスレッドがあります

しかし、どちらのリソースも、CCodeが実際に何をしているのかを理解するのに実際には役立ちません。これは明らかに、ValaがCコードを生成する方法に影響します。ハッカーズガイドからValaまで、CCodeディレクティブは、ValasASTをトラバースするときにCCodeツリーが作成される方法に直接影響を与えると推測できます。

誰かがCCodeが何をするのかもう少し説明できますか?

4

1 に答える 1

8

残念ながら、CCode に関する単独で意味のあるドキュメントはあまり多くありません。必要なのは、Vala に付属の VAPI ファイルと組み合わせて使用​​することです。最も基本的には、おそらく次のようなマクロを使用します。

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

ここでは、cname(つまり、C コードに発行される名前) と(つまり、 dcheader_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 プロトタイプ を持ちますが、 は期待される C プロトタイプint *x(void)y持つヌル終端配列を持つと想定されます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値が引数 0 (つまり、開始) の後に引数を配置し、次に特定の順序で配置されていることがわかります。

クラスと構造体には、初期化、破棄、および参照カウントを処理する関数がありますが、それらはかなり単純です。ジェネリックの扱いも少し複雑です。繰り返しになりますが、VAPI は洞察の最良の情報源です。ただし、基本的な C 関数とマクロを使い始めるには、これで十分です。

于 2012-04-17T03:27:13.547 に答える