在你的 lighttpd 模块中包含 C++ 库和代码¶
深入了解插件¶
Lighttpd 需要一些东西来加载已编译的模块。它的代码入口点是 `plugin_init` 函数,该函数负责设置插件信息,如名称、版本等,以及其他钩子(如 `init`、处理程序等)。为了访问 `plugin_init`,lighttpd 在你的二进制文件中查找 C 风格的符号(即 `mod_rewrite_plugin_init`)。由于我们必须使用 C++ 支持进行编译,因此我们需要明确告诉编译器为该函数使用 C 风格的名称,以便 lighttpd 可以访问它。
设置钩子¶
一旦我们可以调用 `plugin_init`,并且插件已传入到我们的模块中,我们就必须设置钩子。这里的问题是插件数据结构中的这些钩子是 C 风格的函数指针。不保证它与 C++ 函数指针具有相同的调用约定(因编译器而异)。为了完全准确,我们选择指向这些的任何函数都应使用相同的调用约定。
要告诉你的 C++ 编译器使用 C 符号名称和调用约定,请在 `plugin_init` 和你的钩子函数的函数原型周围使用 `extern "C" { /*...*/ }`。(你或许可以省略钩子中的 `extern "C"`,但某些编译器可能会产生意想不到的结果。)
不兼容性¶
不幸的是,在使用 C++ 编译器和 lighttpd 1.5 时,似乎存在一些类型不兼容性。`base.h` 中有几个结构体类型具有同名变量。更改这些变量似乎不切实际,因为它们非常普遍,而且由于启用 C++ 支持似乎不是优先事项,我认为最好创建并包含一个 C++ 兼容性库。请参阅随附的 `*_compat.hpp` 文件,了解我目前正在进行的工作。将它们与 `base.h`、`plugin.h` 等文件一起放在 `src/c++-compat` 中(抱歉使用 hpp 扩展名,但如果没有其他人感兴趣,我将保持不变)。
一些辅助类¶
当然,要在你的模块中使用 C++,你可以做任何你想做的事情,只要你的 `plugin_init` 具有 C 链接。但是,我猜如果你正在考虑为你的模块使用 C++,那么以更 C++ 的方式做事就不会显得格格不入。考虑到这可能会吸引更多对 lighttpd 感兴趣的 C++ 开发者,我没有理由不提供这样的东西。这样的东西在可预见的未来可能会仍然是第三方组件。
单元测试¶
目前,它具有有限的单元测试,由 Google Test 提供。当我有时间时,这将扩展到测试 `datatype_helpers.hpp` 内容。