10

だから、私はFMOD APIを使用していて、それは実際にはCAPIです。

それは悪いことではありません。それだけでは、C++コードとのインターフェースがうまくいきません。

たとえば、

FMOD_Channel_SetCallback( channel, callbackFunc ) ;

のCスタイルの関数callbackFuncが必要ですが、クラスのメンバー関数を渡したいと思います。

私はこれにWin32トリックを使用して、メンバー関数を静的にしました。その後、FMODへのコールバックとして機能します。

ここで、FMODのCネスを説明するために、コードをハックして一部のメンバーを静的にする必要があります。

FMODでそれが可能かどうか、またはコールバックを特定のC ++オブジェクトのインスタンスメンバー関数(静的関数ではない)にリンクする回避策があるかどうか疑問に思います。それははるかにスムーズになります。

4

5 に答える 5

12

メンバー関数を直接渡すことはできません。メンバー関数には暗黙的なパラメーターがthisあり、C関数にはありません。

トランポリンを作成する必要があります(コールバックの署名がわからないため、ここでランダムに何かを実行します)。

extern "C" int fmod_callback( ... args ...)
{
    return object->member();
}

1つの問題は、そのオブジェクトポインタがどこから来るかです。うまくいけば、fmodは、コールバックが行われたときに提供される汎用コンテキスト値を提供します(その後、オブジェクトポインターを渡すことができます)。

そうでない場合は、アクセスするためにグローバルにする必要があります。

于 2010-03-10T20:36:46.867 に答える
5

私はそれがこのように機能するはずだと思います:
あなたはを呼び出すことによっていくつかのユーザーデータをチャネルに割り当てることができますFMOD_Channel_SetUserData。このユーザーデータは、イベントを処理するC++オブジェクトへのポインターである必要があります。FMOD_Channel_GetUserData次に、呼び出しによってそのオブジェクトを抽出し、そのオブジェクトに対してC++インスタンスメソッドを呼び出すCスタイルのコールバックを作成する必要があります。

于 2010-03-10T21:04:57.633 に答える
2

「トランポリン」方式にはない、少なくともスレッドセーフであるという利点を持つ、移植性がなく、かなりハック的なソリューションがあります。

実際の機能マシンコードをその場で生成できます。基本的な考え方は、オブジェクトポインタとメンバー関数ポインタを受け取り、Cコールバック関数としてライブラリに渡すことができるヒープメモリのブロックを提供するコールバック関数のテンプレートがあるということです。呼び出されると、向きを変えてそのオブジェクトのメンバー関数を呼び出します。

それは厄介で、新しいプラットフォームの実装を提供する必要があります(呼び出し規約が変更されるたびに)が、それは機能し、スレッドセーフです。(もちろん、DEPにも注意する必要があります)。他のスレッドセーフな解決策は、スレッドローカルストレージに頼ることです(コールバックがあなたが行った呼び出しと同じスレッドで発生することがわかっていると仮定します)。

サンクを生成する方法の例については、http://www.codeproject.com/KB/cpp/GenericThunks.aspxを参照してください。

于 2010-03-10T21:09:59.820 に答える
1

私の謙虚な意見では、Cコールバックに関数ポインターのみを使用する(追加の個別のオブジェクトポインターを使用しない)ことは、壊れた設計です。

関数が代わりにだった場合FMOD_Channel_SetCallback(channel, callbackFunc, callbackObj)、静的メソッドはオブジェクトのインスタンスを取得してから呼び出しますcallbackObj->func()(これは明らかに非静的である可能性があります)。

于 2010-03-10T20:36:01.167 に答える
0

トランポリンを使用して、メンバー関数を呼び出すオブジェクトへのポインターをグローバル変数または静的変数に格納する必要があります。

Object *x;
void callback_trampoline() { x->foobar(); }
...
FMOD_Channel_SetCallback(CHANNEL, callback_trampoline);
于 2010-03-10T20:38:28.917 に答える