Как разрешить консольной программе принимать данные из функции обратного вызова - PullRequest
1 голос
/ 27 октября 2011

Я думаю, что я прав, полагая, что если у меня есть программа, подобная этой, которая устанавливает функцию обратного вызова.

void MyCallbackFunction(char* data) {
cout << "some data arrived: " << data << endl;
}

int main(){
   //sets up callback
   SetDispatchFunction(&MyCallbackFunction));

   while(1==1) {
  sleep(1000);
   }

   return 0;
}

тогда, потому что это однопоточная программа, и выполнение всегда будет обрабатывать времяв цикле, программа не может обработать обработчик MyCallbackFunction?

Если это так, если я не хочу использовать несколько потоков, какие опции у меня есть, чтобы разрешить обработку функции обратного вызова?

Я решил привести реальный пример для демонстрации.

#include <iostream>

using namespace std;

#define WIN32_LEAN_AND_MEAN
#include <windows.h>


BOOL CALLBACK EnumChildProc(HWND hwndChild, LPARAM lParam)
{
   char szText[100] = {0};
   GetWindowText(hwndChild, szText, 100);
   if (lstrlen(szText) < 1) return true;

   cout << "Window text: " << szText << endl;

   return TRUE;
}

int main(int argc, char* argv[])
{
   //latch onto Google Chrome if running
   HWND windowHandle = FindWindow("Chrome_WidgetWin_0", 0);

   if(windowHandle)
      EnumChildWindows(windowHandle, EnumChildProc, 0);


   //loop so program doesn't stop
   while(1==1) {
      Sleep(2000);
   }

   return 0;
}

1 Ответ

1 голос
/ 27 октября 2011

Функция обратного вызова обычно вызывается в потоке, порожденном сущностью, с которой вы регистрируетесь. Вам понадобится какой-то механизм сигнализации, с помощью которого вы заставите свой основной поток знать о обратном вызове.Всегда желательно не выполнять обработку в потоке, вместо этого следует переключить контекст и выполнить обработку в одном из своих собственных потоков.

Просто рассмотрим в качестве примера:
Главный поток блокирует очередь сообщений (или периодически проверяет ее), ожидая чтения сообщения, и в функции обратного вызова вы отправляете сообщение в эту очередь сообщений.

Вы также можете использовать глобальный защищенный синхронизацией для достижения аналогичной функциональности без очереди сообщений.

Однако, если ваша программа строго однопоточная, то в какой-то момент времени whileцикл будет прерван, и будет выполнена функция обратного вызова, в которой вы можете настроить глобальную переменную, которая затем может быть проверена к тому времени, когда она прервана. Конечно, потребуется синхронизация.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...