Динамический вызов функций-обработчиков в C ++ - PullRequest
1 голос
/ 01 января 2012

Я пытаюсь понять конкретную веб-архитектуру. Существует веб-приложение cgi, которое работает таким образом.

Запрос от веб-браузера поступает на веб-сервер apache, который затем направляется диспетчеру приложений.

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

Скажем, если в браузере есть запрос cmd=_login, диспетчер ищет файл конфигурации, в котором может быть эта запись.

Команда: _login

Обработчик: handle_login ()

Заголовок: login.h

Binary: Exe_name

Итак, каким образом диспетчер приложений может разветвлять двоичный файл cgi (Exe_name) и напрямую вызывать функцию handle_login()?

Может ли конкретный метод вызываться напрямую?

Ответы [ 2 ]

3 голосов
/ 01 января 2012

Существует два основных подхода к разрешению символов.

Встроенное разрешение символов.

В зависимости от вашей системы, вы можете искать обычные функции по имени в скрытомтаблица символов используется во время выполнения.Например, dlopen() и dlsym() в UNIX-подобных системах позволяют загружать библиотеку общих объектов и разрешать функции в этой библиотеке по имени.Windows имеет аналогичные функции LoadLibrary() и GetProcAddress() для динамически связанных библиотек (DLL).Необходимо обратить внимание на понятие видимость .Функции должны быть экспортированы библиотекой для разрешения с помощью этого механизма.Я считаю, что GCC создает экспорт всех функций по умолчанию (видимость общедоступна), а компиляторы Windows по умолчанию ничего не экспортируют.Также обратите внимание, что в Windows вы можете разрешать функции в программе хоста, не загружая внешнюю библиотеку, поскольку дескриптор нулевой библиотеки обозначает исполняемый образ процесса хоста.

В общем, это полно тонкостей и не переносимо.Я не рекомендую вам создавать систему, основанную на этом механизме.

Ручное разрешение символов: маршруты

Современный способ отображения URL-адресов (или частей URL-адресов) на функции заключается в создании URL-адреса маршруты .Этот подход принят большинством современных веб-фреймворков, основанных на парадигме MVC (Ruby on Rails, Django и ASP.NET MVC и многие другие).

Это в основном состоит в построении картыимен (или регулярных выражений) для обратных вызовов (в C ++ это будет указатель на функцию или объект std::function<>).Если ваш компилятор поддерживает новый стандарт, вы должны иметь возможность заполнить объект std::map< std::regex,std::function<void()>> для реализации поиска.

Вот простой (не проверенный) пример:

// GET request for login.
void handle_login_page ()
{
     // CGI handler: read from `std::cin` and write to `std::cout`...
}

// POST request for login.
void handle_login_form ()
{
     // CGI handler: read from `std::cin` and write to `std::cout`...
}

typedef std::function<void()> Handler;
typedef std::map<std::string, Handler> Routes;

void handle_request ( const Routes& routes, const std::string& command )
{
     // locate handler.
     Routes::const_iterator match = routes.find(command);
     if (match == routes.end()) {
         // exit with 404 status.
     }
     const Handler handler = match->second;

     // log access or other pre-processing.
     // ...

     // invoke handler.
     handler();
}

int main ()
{
    Routes routes;
    routes["get_login"] = &handle_login_page;
    routes["post_login"] = &handle_login_form;
    // ...

    // accept a connection.
    // fork.
    // get command name.
    const std::string command = ...;
    handle_request(routes, command);
}
0 голосов
/ 01 января 2012

Вам не совсем понятно, используете ли вы Windows или Linux, но возможность загружать модули и выполнять в них заданную функцию - довольно стандартная функциональность для модулей.

Вот два связанных / полезныхфункции из Win32 API:

LoadLibrary

GetProcAddress

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