С ++ синтаксис обратного вызова в классе - PullRequest
0 голосов
/ 17 июня 2010

Я пытаюсь выяснить синтаксис для регистрации обратного вызова с этим сторонним программным обеспечением.Я думаю, что это, вероятно, основной вопрос, я просто не слишком знаком с C ++.У них есть метод для регистрации функции обратного вызова, чтобы их код мог вызывать функцию в моем коде, когда происходит событие.Они предоставили рабочий пример, который регистрирует обратный вызов из основного файла, но я хочу знать, как это сделать при работе внутри класса

Их сигнатура метода:

smHTRegisterHeadPoseCallback(smEngineHandle engine_handle, void *user_data, smHTHeadPoseCallback callback_fun);

Рабочий пример изосновной файл:

void STDCALL receiveHeadPose(void *,smEngineHeadPoseData head_pose, smCameraVideoFrame video_frame)
{
 ...
}

void main()
{
 ...
 smHTRegisterHeadPoseCallback(engine_handle,0,receiveHeadPose)
 ...
}

Но я хочу использовать это из моего класса

MyClass.h

class FaceEngine
{
public:
 void STDCALL receiveFaceData(void *, smEngineFaceData face_data, smCameraVideoFrame video_frame);
    ...

MyClass.cpp

void FaceEngine::Start(void)
{
 rc = smHTRegisterFaceDataCallback(hFaceAPIEngine,0,&FaceEngine::receiveFaceData);
        ...

Результаты в этой ошибке компилятора:

Error 1 error C2664: 'smHTRegisterFaceDataCallback' : cannot convert parameter 3 from 'void (__stdcall FaceEngine::* )(void *,smEngineFaceData,smCameraVideoFrame)' to 'smHTFaceDataCallback' d:\stuff\programming\visual studio 2008\projects\tut02_vertices\faceengine.cpp 43 Beard

Если мой вопрос не ясен, пожалуйста, дайте мне знать, как я могу уточнить.

Ответы [ 2 ]

1 голос
/ 17 июня 2010

Чтобы использовать член класса в качестве параметра указателя на функцию, вы должны объявить его как static метод. Если вы подумаете об этом, вы поймете, почему. Обычные методы класса незаметно передают указатель на экземпляр при их вызове (this указатель). Механизм обратного вызова не может узнать адрес экземпляра класса, метод-член которого вы хотите вызвать. Так что, к сожалению, вы теряете автоматическую возможность доступа к данным экземпляра в режиме обратного вызова.

0 голосов
/ 17 июня 2010

Вам нужно использовать функцию батута, так как функции-члены не могут быть вызваны без экземпляра:

void STDCALL trampoline(void* data, smEngineHeadPoseData hp, smCameraVideoFrame vf) {
    static_cast<FaceEngine*>(data)->receiveFaceData(hp, vf);
}

// ... register:
smHTRegisterFaceDataCallback(hFaceAPIEngine, static_cast<void*>(this), &trampoline);

Обратите внимание, что для передачи указателя this используется параметр user-data, поэтомуФункция trampoline знает, на каком экземпляре вызывать функцию-член.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...