Прежде всего, я должен признать, что мои навыки программирования довольно ограничены, и я взял (действительно небольшой) существующий проект 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*);
Также в моем классе есть открытая функция void "StartGrab", которая должна запускать Grab. Внутри я пытаюсь позвонить:
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 в синглтоне? Или мне нужен отдельный класс Hook и, если да, как я могу получить доступ к функциям MyFrameGrabber? Заранее спасибо.
ВТОРОЕ РЕДАКТИРОВАНИЕ 15.01.08:
Я применил изменения, и теперь они компилируются и связываются. К сожалению, я пока не могу проверить это во время выполнения, потому что это DLL, и у меня пока нет Debug Caller Exe, и есть другие проблемы во время инициализации и т. Д. Я отмечу сообщение как ответ, потому что я уверен, что это правильный способ сделать это.