Member 12278335 Ответов: 1

Не могу вызвать функцию диспетчеризации внутри класса...


Я мог бы написать программу для Microsoft Flight Simulator x. Когда я помещаю в dll или помещаю в класс, я не могу вызвать функцию диспетчеризации "
MyDispatchProcMI
" без параметров...

Что я уже пробовал:

// в файл Хед

#include <iostream>
#include <windows.h>
#include<string>
#include <tchar.h>
#include <stdio.h>
#include <strsafe.h>
#include "SimConnect.h"

using namespace std;
namespace myDllNamespace
{
	HANDLE  hSimConnect = NULL;
	HRESULT hr;
	int     quit = 0;
	HANDLE  hSimConnect = NULL;

	static enum GROUP_ID {
		GROUP_MENU
	};

	static enum EVENT_ID {
		EVENT_MENU_ONE,
		EVENT_MENU_TWO,
	};

	static int menuUseCount = 0;
	class myDll{
	public:
		static __declspec(dllexport)void InitSimConnect();
		static __declspec(dllexport)void DeInitSimConnect();
		static int CALLBACK *MyDispatchProcMI(SIMCONNECT_RECV* , DWORD , void *);
	};
}


/// in cpp file

<pre>
#include "dllHeader.h"

namespace myDllNamespace {


	 int CALLBACK* myDll::MyDispatchProcMI(SIMCONNECT_RECV* pData, DWORD cbData, void *pContext)
	{
		switch (pData->dwID)
		{
			case SIMCONNECT_RECV_ID_EVENT:
			{
											 SIMCONNECT_RECV_EVENT *evt = (SIMCONNECT_RECV_EVENT*)pData;

											 switch (evt->uEventID)
											 {
												 case EVENT_MENU_ONE:
													 printf("\nMenu item one selected %d", evt->dwData);

													 ++menuUseCount;

													 // Selected four times, so replace item one with item two
													 if (menuUseCount == 4)
													 {
														 hr = SimConnect_MenuDeleteItem(hSimConnect, EVENT_MENU_ONE);
														 hr = SimConnect_RemoveClientEvent(hSimConnect, GROUP_MENU, EVENT_MENU_ONE);

														 hr = SimConnect_MenuAddItem(hSimConnect, "Menu Item Two", EVENT_MENU_TWO, 54321);
														 hr = SimConnect_AddClientEventToNotificationGroup(hSimConnect, GROUP_MENU, EVENT_MENU_TWO);
													 }
													 break;

												 case EVENT_MENU_TWO:

													 ++menuUseCount;

													 printf("\nMenu item two selected %d", evt->dwData);

													 if (menuUseCount == 6)
														 quit = 1;
													 break;

												 default:
													 printf("\nReceived unknown event: %d", evt->uEventID);
													 break;
											 }
											 break;
			}

			case SIMCONNECT_RECV_ID_QUIT:
			{
											quit = 1;
											break;
			}

			default:
				printf("Received ID: %d", pData->dwID);
				break;
		}
		return 0;
	}

	void myDll::InitSimConnect()
	{

		if (SUCCEEDED(SimConnect_Open(&hSimConnect, "Menu Items", NULL, 0, 0, 0)))
		{
			printf("\nConnected to Flight Simulator!");

			// Create some private events
			hr = SimConnect_MapClientEventToSimEvent(hSimConnect, EVENT_MENU_ONE);
			hr = SimConnect_MapClientEventToSimEvent(hSimConnect, EVENT_MENU_TWO);

			// Add one menu item
			hr = SimConnect_MenuAddItem(hSimConnect, "Menu Item One", EVENT_MENU_ONE, 12345);


			// Sign up for the notifications
			hr = SimConnect_AddClientEventToNotificationGroup(hSimConnect, GROUP_MENU, EVENT_MENU_ONE);

			hr = SimConnect_SetNotificationGroupPriority(hSimConnect, GROUP_MENU, SIMCONNECT_GROUP_PRIORITY_HIGHEST);

			while (0 == quit)
			{
				SimConnect_CallDispatch(hSimConnect, MyDispatchProcMI, NULL);
				Sleep(1);
			}

			// Clean up before exiting
			if (menuUseCount < 4)
				hr = SimConnect_MenuDeleteItem(hSimConnect, EVENT_MENU_ONE); else
				hr = SimConnect_MenuDeleteItem(hSimConnect, EVENT_MENU_TWO);

			hr = SimConnect_Close(hSimConnect);



		}
	}

}

KarstenK

В чем вопрос? Пожалуйста, отладьте детальную ошибку и переформатируйте свой код!!!!

Richard MacCutchan

Я думаю, что MyDispatchProcMI должен быть static метод.

Richard MacCutchan

Ваша декларация и определение противоречат друг другу. Вы не можете объявить что-то как указатель, а затем переопределить его как метод класса.

1 Ответов

Рейтинг:
11

KarstenK

Это абсолютно очевидно, потому что объявление вашей функции:

static int CALLBACK *MyDispatchProcMI(SIMCONNECT_RECV* , DWORD , void *);

таким образом, обратный вызов получает канал с некоторыми данными, их размером и некоторым контекстом. Это обычная имплементация для таких вещей. Обычно контекст - это дескриптор или указатель на целевой объект, а данные-некоторая информация о том, что происходит.

Такой обработчик есть вызывается из контекстного объекта и не мануэлли. Если он не будет вызван, ваша настройка не будет правильной или неполной.