Член класса как обработчик события для события в стиле C в C ++ - PullRequest
1 голос
/ 24 сентября 2019

Я работаю с Android NDK.У нас есть основной метод, такой как:

void android_main(struct android_app *app)
{
    // onAppCmd is the event:
    app->onAppCmd = engine_handle_cmd;
}

Определение engine_handle_cmd:

static void engine_handle_cmd(struct android_app *app, int32_t cmd)
{
    // Event handling code here...
}

Вместо использования статического метода, как описано выше, я хотел бы создать синглтонКласс менеджера событий и используйте его для обработки события onAppCmd, как показано ниже:

Объявление менеджера событий:

#pragma once

class EventManager
{
public:
   static EventManager &getInstance();
   void handleCommand(struct android_app *app, int32_t cmd);
   ~EventManager();
private:
   EventManager();
   EventManager(EventManager const&);
   void operator=(EventManager const&);
};

Тогда определение класса:

#include "EventManager.h"

EventManager &EventManager::getInstance()
{
   static EventManager instance;
   return instance;
}

EventManager::~EventManager() {}

EventManager::EventManager() {}

void EventManager::operator=(EventManager const &) {}

void EventManager::handleCommand(struct android_app *app, int32_t cmd)
{
   // Event handling code...
}

Теперь, когда я пытаюсь в моем методе:

void android_main(struct android_app *app)
{
    EventManager &manager = EventManager::getInstance();
    app->onAppCmd = manager.handleCommand();
}

Я получаю ошибку компилятора:

reference to non-static member function must be called.

Если я попробую следующее:

void android_main(struct android_app *app)
{
    EventManager &manager = EventManager::getInstance();
    app->onAppCmd = &manager.handleCommand();
}

Я получаю сообщение об ошибке компилятора:

cannot create a non-constant pointer to member function.

Могу ли я в любом случае заставить этот подход работать без использования метода static?Любые предложения для практики ставок на классах обработчиков событий также приветствуются.Спасибо.

1 Ответ

1 голос
/ 24 сентября 2019

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

void callback_wrapper1(struct android_app *app, int32_t cmd)
{
    EventManager &manager = EventManager::getInstance();
    // do singleton stuff here
}

void android_main(struct android_app *app)
{
    app->onAppCmd = &callback_wrapper1;
}

Если вам не нравится ваш синглтон в обратном вызове, вы также можете использовать выделенное поле из android_app для передачи общих данных в обратный вызов:

void callback_wrapper2(struct android_app *app, int32_t cmd)
{
    EventManager &manager = *static_cast<EventManager*>(app->userData);
    // do what you want here
}

void android_main(struct android_app *app)
{
    app->userData = static_cast<void *>(&EventManager::getInstance());
    app->onAppCmd = &callback_wrapper2;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...