特定のサードパーティAPIで概説されている一連の関数をラップするラッパークラスを作成しています。このような非メンバー関数をラップしようとすると、次のようになります。
(AVTcamDllWrapper.h)
typedef VmbErrorType (WINAPI * AVTGETCAMERAS) (CameraPtrVector cameras);
class CAVTcamDllWrapper
{
HMODULE mAVTCamLibrary; //I later have this point to the DLL
public:
void AVTGetCameras (CameraPtrVector cameras);
};
(AVTcamDllWrapper.cpp)
void CAVTcamDllWrapper::AVTGetCameras(AVTNS CameraPtrVector cameras)
{
AVTGETCAMERAS pFunc = NULL;
pFunc = (AVTGETCAMERAS) GetProcAddress(mAVTCamLibrary, "?GetCameras@VimbaSystem@VmbAPI@AVT@@AEAA?AW4VmbErrorType@@PEAV?$shared_ptr@VCamera@VmbAPI@AVT@@@23@AEAI@Z");
DWORD dw = GetLastError();
if(pFunc == NULL)
{
Exlog(L"CAVTcamDllWrapper::AVTGetCameras: Failed to locate AVTGetCameras method in AVTCamera DLL.");
NIERR_SET_AND_THROW_ERROR(NIERR_CAMERA_ERROR, L"Failed to locate AVTGetCameras method in AVTCamera DLL.");
}
VmbErrorType vErr = pFunc(cameras);
if(vErr != VmbErrorSuccess)
{
wstring exLogMsg = Format(exLogMsg, L"CAVTcamDllWrapper::AVTGetCameras(): Failed to get any cameras. VmbErrorType = %d", vErr);
Exlog(exLogMsg.c_str());
NIERR_SET_AND_THROW_ERROR(NIERR_CAMERA_ERROR, L"Failed to get any cameras.");
}
}
上記のコードは、非メンバー関数に最適です。たとえば、次のように言うだけで呼び出される関数をラップしようとしている場合です。
CallFunction(blah, blaaaaah);
その後、ラッパークラスは正常に機能し、pFuncは適切に設定され、VmbErrorType vErr = pFunc();
行でエラーは発生しません。
ただし、私の関数の多くはメンバー関数であり、次のように呼び出されます。
SomeObject.CallMemberFunction(blah, bleh);
// or
SomeObjectPointer->CallMemberFunction(what, ever);
これらは私がラップできないように見える関数です。次の行でエラーが発生します。
VmbErrorType vErr = pFunc();
関数は、それを呼び出す特定のオブジェクトなしでは呼び出すことができないためです。私の例では、Camera内に存在する関数GetCamerasをラップしています。関数をラップせずに呼び出すには、カメラポインターのベクトルを作成し、次のようにします。
cameras[0]->GetCameras(VmbAccessModeFull);
動作します。cameras[0]
しかし、GetCamerasの呼び出しは依存しており、呼び出し元のカメラがないと完全に役に立たないため、この関数をどのようにラップするのかわかりません。
では、上記のようなメンバー関数をラップするにはどうすればよいですか?
編集1:
特定のオブジェクトへの参照を渡そうとしましたが、
VmbErrorType vErr = theObject->pFunc();
しかし、明らかにこれは機能しません。これは、オブジェクト内に存在しないpFuncという名前の関数を探すためです。
編集2:
ラッパー関数を変更して、参照オブジェクトをパラメーターなどとして渡すようにしたいと思います。したがって、通常の代わりに:
cameras[0]->GetCameras(VmbAccessModeFull);
いくつか変更して、ラッパー関数を次のようにする必要があります。
mWrapperObject->WrappedGetCameras(VmbAccessModeFull, cameras[0]);
ラップされた関数がメンバー関数として機能するために必要なコンテキストを持つようにします。