#c #windows
#c #Windows
Вопрос:
При попытке вызвать нестатическую функцию возникает ошибка нарушения доступа.
мой .h
файл выглядит следующим образом.
class World
{
public:
World();
virtual ~World();
static void CALLBACK DispatchCallback(
SIMCONNECT_RECV *pData,
DWORD cbData,
void *pContext
);
void Process(SIMCONNECT_RECV *pData, DWORD cbData);
virtual void frameEvent();
virtual void init();
};
Теперь в моем .cpp-файле функция init() вызывает функцию, которая возвращает данные в мою функцию обратного вызова.
SimConnect_CallDispatch(hSimConnect, DispatchCallback, NULL);
Которая отправляет данные в DisPatchCallback
функцию.
В этой функции находится следующий код:
void CALLBACK World::DispatchCallback(
SIMCONNECT_RECV *pData,
DWORD cbData,
void *pContext)
{
World *pThis = reinterpret_cast<World*>(pContext);
pThis->Process(pData, cbData);
}
эта функция является статической функцией, которая создает мировой объект для вызова функции процесса.
Это работает, но прерывается в строке, где требуется получить доступ к функции frameEvent .
void World::Process(SIMCONNECT_RECV *pData, DWORD cbData)
{
HRESULT hr;
switch(pData->dwID)
{
case SIMCONNECT_RECV_ID_EVENT_FRAME:
frameEvent(); //it breaks here frameEvent is a non static function
break;
}
}
Местоположение чтения 0x00000000 с нарушением доступа.
Может кто-нибудь указать мне правильное направление для решения этой проблемы.?
Если вам интересно, я пишу плагин для Microsoft Flight Simulator X.
Я пытаюсь реализовать simconnect.h
oo-способом. Msdn показывает пример, который я пытаюсь реализовать.
class CName
{
void Dispatch();
static void DispatchCallback(
SIMCONNECT_RECV *pData,
DWORD cbData,
void *pContext
);
void Process(SIMCONNECT_RECV *pData, DWORD cbData);
HANDLE hSimConnect; // use SimConnect_Open to set this value.
};
void CName::Dispatch()
{
::SimConnect_Dispatch(hSimConnect, amp;CName;::DispatchCallback, this);
}
// static function
void CName::DispatchCallback(
SIMCONNECT_RECV *pData,
DWORD cbData,
void *pContext)
{
CName *pThis = reinterpret_cast<CName*>(pContext);
pThis->Process(pData, cbData);
}
void CName::Process(SIMCONNECT_RECV *pData, DWORD cbData)
{
// do processing of SimConnect data
}
Надеюсь, я дал достаточно информации.
Комментарии:
1. Чего вы пытаетесь достичь с помощью статических функций с контекстом? И, в общем, использование
casts
таким образом указывает на плохое проектирование…2. @Griwes: на самом деле это очень распространенный шаблон при написании кода на C с использованием C API-интерфейсов — вы передаете его в
this
качестве параметра контекста вместе сstatic
функцией обратного вызова, которая перенаправляет обратный вызов в метод класса объекта. Он используется с оконными процедурами, потоковыми процедурами, обратными вызовами библиотеки и т. Д.
Ответ №1:
Вы передаете NULL
в качестве параметра контекста SimConnect_CallDispatch
, поэтому ваш обратный вызов понятия не имеет, какой World
объект вызывать Process
— как это возможно, если вы не указываете это? Измените вызов на передачу в this
качестве параметра контекста, как в примере:
SimConnect_CallDispatch(hSimConnect, DispatchCallback, this);
Комментарии:
1. Спасибо, мне немного стыдно, что я упустил из виду, что это так очевидно!
Ответ №2:
Ваше использование:
SimConnect_CallDispatch(hSimConnect, DispatchCallback, NULL);
кажется очень подозрительным. Что NULL
означает параметр при вызове этой функции? Это так pContext
?
Ответ №3:
Он прерывается, потому this
что равен NULL .
Проверьте эту часть вашего кода:
World *pThis = reinterpret_cast<World*>(pContext);
pThis->Process(pData, cbData);
Если reinterpret_cast
сбой получает значение NULL — оно возвращает значение NULL, и вы его не проверяете.
Комментарии:
1.
reinterpret_cast
не может произойти «сбой» — либо он компилируется, либо нет. ЕслиpThis
равно null , то такжеpContext
должно быть null .