我正在尝试了解特定的Web架构。 有一个cgi Web应用程序以这种方式工作。
来自Web浏览器的请求来到apache Web服务器,然后将其路由到应用程序调度程序。
应用程序调度程序有一个配置文件,其中包含所有可能的命令及其相应的处理程序方法。
假设,如果浏览器发出cmd=_login
请求,调度程序会查找可能包含此条目的配置文件。
命令:_login
处理程序:handle_login()
标题:login.h
二进制:Exe_name
那么,应用程序调度程序可以通过什么方式分叉cgi二进制文件(Exe_name)并直接调用handle_login()
函数?
可以直接调用特定方法吗?
答案 0 :(得分:3)
基本上有两种方法可以进行符号解析。
根据您的系统,您可以在运行时使用的隐藏符号表中按名称查找常规函数。例如,类UNIX系统上的dlopen()
和dlsym()
允许您加载共享库,并按名称解析该库中的函数。对于动态链接库(DLL),Windows具有类似的行为函数LoadLibrary()
和GetProcAddress()
。您必须注意可见性的概念。函数必须由库导出才能使用此机制进行解析。我相信GCC默认创建导出所有功能(可见性是公共的),Windows编译器默认不导出任何内容。另请注意,在Windows上,您可以在不加载外部库的情况下解析主机程序中的函数,因为空库句柄指定了主机进程的可执行映像。
一般来说,这充满了细微之处,而且不便携。我不建议您基于此机制构建系统。
将URL(或部分URL)映射到函数的现代方法是构建URL routes 。大多数基于MVC范例(Ruby on Rails,Django和ASP.NET MVC等)的现代Web框架都采用了这种方法,其中还有很多其他方法。
这基本上包括构建一个名称(或正则表达式)到回调的映射(在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);
}
答案 1 :(得分:0)
您不清楚自己是使用Windows还是Linux,但是加载模块并在其中执行给定功能的能力是模块的标准功能。
以下是Win32 API中的两个相关/有用的功能: