まず第一に、私のプログラミングスキルはかなり限られていることを認めなければなりません。私は(本当に小さな)既存のC ++ OOPプロジェクトを引き継いで、自分のものを押し込もうとしました。残念ながら、私は自分の知識を超えた問題を経験しています。ここで助けを見つけたいと思います。私はカメラから画像を取得するためにサードパーティのライブラリ(変更できません)を使用しており、ここではいくつかのプレースホルダー名を使用します。
サードパーティのライブラリには、継続的なライブグラブを開始する関数「ThirdPartyGrab」があり、新しいフレームが到着するたびに呼び出される関数へのポインタを取得します。したがって、通常のCアプリケーションでは、次のようになります。
ThirdPartyGrab (HookFunction);
「HookFunction」は次のように宣言する必要があります。
long _stdcall HookFunction (long, long, void*);
または、次のように宣言されている「BUF_HOOK_FUNCTION_PTR」
typedef long (_stdcall *HOOK_FUNCTION_PTR) (long, long, void*);
これで、C++アプリケーションとクラス「MyFrameGrabber」ができました。これは私が行うすべてのことをカプセル化する必要があります。だから私は次のようなプライベートメンバーとしてフック関数を入れました:
long _stdcall HookFunction (long, long, void*);
また、私のクラスには、Grabを開始するパブリックvoid関数「StartGrab」があります。内部で私は電話しようとします:
ThirdPartyGrab (..., HookFunction, ...);
これは(当然のことながら)失敗します。MyFrameGrabber :: HookFunctionの関数呼び出しで引数リストが欠落しているため、代わりに&MyFrameGrabber::HookFunctionを使用してポインターを作成する必要があると表示されます。ただし、代わりに「&MyFrameGrabber :: HookFunction」を渡すと、これをBUF_HOOK_FUNCTION_PTRに変換できないという別のエラーが発生します。
C ++ FAQ関数ポインタを読んだ後、私は問題を理解していると思いますが、解決策を作ることができません。フック関数を静的にしようとしましたが、これも変換エラーになります。フック関数をクラスの外に置くことも考えましたが、フック関数の中にクラス関数を使用する必要があります。別の方法はありますか、それともコンセプト全体を変更する必要がありますか?
編集14.01.08:サードパーティのライブラリを変更できず、voidポインターはフック関数内で使用されるデータ専用であるため、シングルトンの回避策をテストしました。残念ながら、思ったようにそのままでは機能しませんでした。静的関数を別のクラスに入れる必要があるかどうかわからないので、「MyFrameGrabber」クラスに入れました。
static MyFrameGrabber& instance()
{
static MyFrameGrabber _instance;
return _instance;
}
long Hook(long, long, void*); // Implementation is in a separate cpp file
私のcppファイルには、call_hook関数があります。
long MFTYPE call_hook(long x, MIL_ID y, void MPTYPE *z)
{
return MyFrameGrabber::instance().Hook(x,y,z);
}
void
MyFrameGrabber::grab ()
{
ThirdPartyGrab(..., call_hook, ...);
}
しかし、これにより、static MatroxFrameGrabber _instance;
一致する標準コンストラクターが見つからないというエラーが発生します。MyFrameGrabberコンストラクターは次のようになっているので、これは正しいです。
MyFrameGrabber (void* x,
const std::string &y, int z,
std::string &zz);
空のコンストラクターを入れようとしましたMyFrameGrabber();
が、リンカーエラーが発生します。シングルトンでMyFrameGrabberコンストラクターに空のパラメーターを渡す必要がありますか?または、別のフッククラスが必要ですか?はいの場合、MyFrameGrabber関数にアクセスするにはどうすればよいですか?前もって感謝します。
2番目の編集15.01.08:変更を適用すると、コンパイルとリンクが行われます。残念ながら、これはDLLであり、Debug Caller Exeがまだなく、初期化中などに他の問題があるため、実行時にまだテストできません。これが正しい方法であると確信しているため、投稿を回答としてマークします。