2

私は、D 言語 ( http://d-programming-language.org/ ) の Clutter バインディングを作成する可能性を探っており、libclutter の動的ロードを使用していくつかの簡単なテストを試すことから始めました。GObject 継承システムに由来する可能性のある問題に遭遇しました。解決方法を教えていただければ幸いです。概要は次のとおりです。clutter_stage_get_default を使用すると、clutter_actor_* メソッドで使用できる ClutterActor* が返されます。しかし、clutter_stage_* または clutter_container_* メソッドを使用すると、常にエラーまたは segfault が発生します。ここに私のテストコードがあります: http://pastebin.com/nVrQ69dU

56 行目の clutter_container_add_actor 呼び出しで、次のエラーが発生します。 (<unknown>:11976): Clutter-CRITICAL **: clutter_container_add_actor: assertion 'CLUTTER_IS_CONTAINER (container)' failed

サンプル コードでは、キャスト用の CLUTTER_STAGE および CLUTTER_CONTAINER マクロに気付きました (これらは明らかに利用できません)。これが正しくなく、キャストする前にステージ ポインターで Gobject タイプのマジックを実行する必要がある場合は、お知らせください。clutter_stage_set_title または clutter_stage_set_color をバインドして使用するとcast(ClutterStage*)stage、おそらく同じ問題で、セグメンテーション違反が発生しました。

編集:これは、外部依存関係のない簡素化された例です (Linux を使用していない場合は、dl 呼び出しを OS の同等のものに置き換える必要があります)。このコードは、GDB と Valgrind によると、segfault で失敗します。clutter_stage_set_title (in /usr/lib/libclutter-glx-1.0.so.0.600.14)

4

2 に答える 2

2

問題は、C 関数を として宣言していないことですextern(C)。そのため、dmd は D 関数を呼び出していると判断し、間違った呼び出し規則を使用します。これを正しく行う 1 つの方法は次のとおりです。

alias extern(C) void function(void*, const char*) setTitleFunc;
auto clutter_stage_set_title = getSym!(setTitleFunc)("clutter_stage_set_title");

ただし、エイリアスなしで機能させる方法がわかりません。extern(C)DMDは、テンプレート パラメーターで何かを解析することを拒否します。

auto clutter_stage_set_title = getSym!(extern(C) void function(void*, const char*))("clutter_stage_set_title"); //Doesn't work

ところで: あなたのcstring関数は危険です: 文字列を変更できることを示す char* を返しますが、これが常に正しいとは限りません: 文字列リテラルを渡すと、toStringz新しいメモリが割り当てられず、代わりに元の文字列のポインターが返される場合があります。文字列リテラルは読み取り専用メモリにあるため、問題が発生する可能性があります。

関数型を調整して C 型 ( const gchar*C 内 --> const char*D 内) に一致させ、toStringz を直接使用することができます。

于 2011-06-07T08:49:01.150 に答える
0

Dの構造体は相互に継承できず、構造体ポインターをキャストするvoid*と、(Cキャストとは異なり)中間キャストがない限りnullが返されます。ここで反論しました。

ハンドルラッピング構造体を使用して別の抽象化レイヤーを追加し、キャスト時にそれらのマクロからのチェックをエミュレートすることをお勧めします

しかし、あなたがそうするとどうなりますか

clutter_container_add_actor(cast(ClutterContainer*)(cast(void*)stage), textbox);

(最初にvoid *にキャストし、次にClutterContainer *にキャストします)

于 2011-06-06T20:30:00.730 に答える