1

QT アプリケーションで外部ライブラリにリンクしようとしています。外部ライブラリには、呼び出しようとしている次の関連コードを含むヘッダー ファイルがあります。

 extern VGRABDEVICE_API bool V_AssignFrameSizeCallback(IGrabChannel* pChannel, void* pFunc);

提供されているデモ C++ プログラムでは、コンパイルに問題はありません。次の関連コードは次のとおりです。

// in main.cpp    
void _stdcall MyFrameSizeCallback(T x) {
    do_stuff;
}

int main(int argc, char* argv[]) {
    IGrabChannel* pChannel0 = something;
    V_AssignFrameSizeCallback(pChannel0, MyFrameSizeCallback);
}

このコードを QT アプリケーションに組み込もうとしていますが、問題が発生しています。私のmainwindow.cppファイルで:

void _stdcall MainWindow::MyFrameSizeCallback(T x) {
    do_stuff;
}

void MainWindow::someFunction() {
    IGrabChannel* pChannel0 = something;
    V_AssignFrameSizeCallback(pChannel0, &MainWindow::MyFrameSizeCallback);
}

私が得ているエラーは次のとおりです。

error: C2664: 'bool V_AssignFrameSizeCallback(IGrabChannel *,void *)' :
cannot convert argument 2 from 'void (__cdecl MainWindow::* )(T)' to 'void *'
There is no context in which this conversion is possible

私は何をする必要がありますか?ありがとう。

4

1 に答える 1

3

2 つの問題があります。まず、void*関数ポインタではなく、データ ポインタです。C++ 標準によると、2 つの間のキャストは機能しないと想定されています。一部のプラットフォームでは、より強力な保証が提供されます...たとえば、WindowsGetProcAddressと *nixでは、dlsymこの 2 つが混在しています。

次に、 your&MainWindow::MyFrameSizeCallbackは関数ポインタではなく、メンバ関数へのポインタです。それを呼び出すにはMainWindow、外部ライブラリが何も知らないオブジェクトが必要です。

ライブラリにはメンバー関数ではなく、通常の関数を提供する必要があります。オブジェクト ポインターを取得する何らかの方法がある場合は、MainWindow*そのメンバー関数を呼び出して実際の作業を行うことができます。ライブラリは、コールバックに渡される「コンテキスト」パラメータを提供する場合があります。これは、オブジェクト ポインターを配置するのに最適な場所です。MainWindow*それ以外の場合は、グローバル変数に保存する必要があります。1つだけあれば簡単ですが、複数ある場合はstd::map<IGrabChannel*, MainWindow*>.

コード:

MainWindow* MainWindow::the_window;

void MainWindow::MyFrameSizeCallback(T x)
{
    do_stuff;
}

void _stdcall MyFrameSizeCallbackShim(T x)
{
    MainWindow::the_window->MyFrameSizeCallback(x);
}

void MainWindow::someFunction()
{
    IGrabChannel* pChannel0 = something;
    the_window = this;
    V_AssignFrameSizeCallback(pChannel0, &MyFrameSizeCallbackShim);
}

パラメータxが でない場合はIGrabChannel、マップのデータ型と挿入ロジックを適宜変更してください。パラメータxが予測可能な一意の識別子ではない場合、1 つのMainWindowインスタンスへのコールバックのみに制限される可能性があります。

于 2014-12-05T20:41:09.940 に答える