11

Vala を使用して、既存の GLib ベースの C プロジェクトをハックしたいと思います。

基本的に私がやっていることは、ビルド プロセスの開始時に、valac を使用して .vala ファイルから .c および .h ファイルを生成し、生成されたファイルを .c または .h ファイルと同じようにコンパイルすることです。

これはおそらく最善の方法ではありませんが、ほとんどの場合問題なく機能しているようです。

私の問題は、Vala コードから既存の C コードにアクセスするのに苦労していることです。これを行う簡単な方法はありますか?

独自の .vapi ファイルを書き込もうとしましたが (vala に付属のツールではうまくいきませんでした)、これらの書き方に関する適切なドキュメントが見つかりません。

存在しますか?既存の C コードを呼び出すには、これらのファイルのいずれかが必要ですか?

4

4 に答える 4

15

はい、C 関数を呼び出すには、バインディングを記述する必要があります。プロセスはhttp://live.gnome.org/Vala/Tutorial#Binding_Libraries_with_VAPI_Filesで説明されていますが、これは GObject なしで記述されたカスタム関数またはライブラリには直接適用されません。非 GObject ライブラリの複雑なバインドがある場合は、おそらく #vala IRC チャネルの助けが必要になるでしょう。

ただし、ほとんどの場合、単純な vapi ファイルを使用して、autoconf 定義またはプレーン C で記述された関数をバインドします。これは、効率上の理由または vala の破損、またはその他の理由によるものです。そして、これはほとんどの人が行う方法です:

myfunc.vapi

[CCode (cheader_filename = "myfunc.h")]
namespace MyFunc {
    [CCode (cname = "my_func_foo")]
    public string foo (int bar, Object? o = null);
}

myfunc.h (およびプロジェクトにリンクされた .c 内の対応する実装)

#include <glib-object.h>
char* my_func_foo(int bar, GObject* o)

example.vala は

using MyFunc;

void main() {
    baz = foo(42);
}

valac でコンパイルする場合、 myfunc.vapi--vapidir=のディレクトリの場所を指定するために使用します。ビルド システムによっては、すべてをリンクするために、valac または gcc CFLAGS に追加の引数を渡す必要がある場合があります。

于 2010-03-24T23:12:46.040 に答える
1

C で記述された GLib ベースのライブラリの場合、C ソースから gir ファイルを生成することができます: Vala/Bindings

手動でも問題ありません。文字列を受け取る do_something というメソッドを使用して、C で SomelibClass1 を定義するライブラリがあるとします。ヘッダーファイルの名前は「somelib.h」です。次に、対応する vapi は次のように単純です。

somelib.vapi:

[CCode (cheader_filename="somelib.h")]
namespace Somelib {
   public class Class1 {
      public void do_something (string str);
   }
}

GLib 以外のライブラリ用の vapis を作成するためのドキュメントは、Vala/LegacyBindingsにあります。

これは実際にはとても簡単です。posix.vapi からの抜粋を見てみましょう:

[Compact]
[CCode (cname = "FILE", free_function = "fclose", cheader_filename = "stdio.h")]
public class FILE {
    [CCode (cname = "fopen")]
    public static FILE? open (string path, string mode);

    [CCode (cname = "fgets", instance_pos = -1)]
    public unowned string? gets (char[] s);
}

これにより、次の C 関数が実装されます。

FILE *fopen (const char *path, const char *mode);
char *fgets (char *s, int size, FILE *stream);

instance_pos 属性を破棄すると、vala はオブジェクトがメソッドの最初のパラメーターであると想定します。このようにして、大まかにオブジェクト指向の c-construct をバインドすることができます。オブジェクトが逆参照されると、コンパクト クラスの free_method が呼び出されます。

メソッド、クラス、構造体などの CCode(cname) 属性は、C での名前と同じでなければなりません。

このテーマには他にもたくさんありますが、これで一般的な概要がわかります。

于 2014-04-13T09:09:28.237 に答える
1

エルマルコの答えに私が加える唯一の追加はexternキーワードです。パッケージの 1 つまたは標準の C/Posix ライブラリで既に利用可能な単一の C 関数にアクセスしようとしている場合は、この方法で簡単にアクセスできます。

于 2010-11-03T00:12:18.933 に答える
-1

おそらく、c から vala コードにアクセスする方が簡単でしょう。あなたがしなければならないことは、Cにコンパイルするだけです。

于 2010-12-24T09:18:42.083 に答える