Я модифицирую драйверы дисплея, чтобы получать уведомления об обновлениях, отправленные с USB-порта. Пока все хорошо, но у меня есть запас на следующие:
GPEFlat::GPEFlat()
{
PBOOT_ARGS args;
ULONG fbSize;
ULONG fbOffset;
ULONG offsetX;
ULONG offsetY;
BOOL bFoundArgs = FALSE;
BOOL m_MouseDisabled = TRUE;
HANDLE m_hAttachEvent = CreateEvent(NULL, FALSE, FALSE, L"MouseAttached");
HANDLE m_hDetachEvent = CreateEvent(NULL, FALSE, FALSE, L"MouseDetached");
HANDLE m_hCursorThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MouseEventThread, NULL, 0, NULL);
DWORD
GPEFlat::MouseEventThread(void)
{
DWORD rc = TRUE;
HANDLE handles[2];
handles[0] = m_hAttachEvent;
handles[1] = m_hDetachEvent;
В результате возникает ошибка:
Ошибка 1 ошибка C2440: «приведение типа»: невозможно преобразовать драйверы «перегруженной функции» в драйверы «LPTHREAD_START_ROUTINE» \ display \ vgaflat
Итак, строка: HANDLE m_hCursorThread = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) MouseEventThread, NULL, 0, NULL);
Досн работы. Получил некоторые указания, что это может быть нестатическим методом.
Как мне это сделать?
Привет
Важно понимать, что функции (включая статические методы) и нестатические методы — это разные вещи. CreateEvent
ожидает функцию. Вы должны дать ему это, он не будет работать с GPEFlat::MouseEventThread
потому что это метод. Что вы можете сделать, это дать ему функцию, которая вызывает GPEFlat::MouseEventThread
, Обычно это делается так
DWORD WINAPI thread_starter(LPVOID that)
{
return ((GPEFlat*)that)->MouseEventThread();
}
...
CreateThread(NULL, 0, thread_starter, this, 0, NULL);
Обратите внимание, что я прохожу this
в CreateThread
это очень важно. CreateThread
передает его параметру that
в thread_starter
, который использует that
чтобы вызвать метод, который вы хотели вызвать все время.
MouseEventThread
должен быть static
функция, потому что указатель на функцию не такой же, как указатель на функцию-член. Статические методы могут использоваться как обычные указатели на функции, но нестатические функции-члены не могут.
Если вам нужно сослаться на членов класса, то одно очень простое решение — иметь статические функции-обертки, которые принимают экземпляр объекта (this
в конструкторе), а затем вызывает фактическую функцию-член, используя этот указатель экземпляра.
Что-то вроде
class GPEFlat
{
// ...
private:
static DWORD MouseEventThreadWrapper(LPVOID instance)
{ return reinterpret_cast<GPEFlat*>(instance)->MouseEventThread(); }
// ...
};
Вместо этого создайте поток с этой функцией-оберткой, передав this
в качестве аргумента к этому:
GPEFlat::GPEFlat()
{
// ...
HANDLE m_hCursorThread = CreateThread(
NULL, 0, (LPTHREAD_START_ROUTINE)MouseEventThreadWrapper, this, 0, NULL);
}