Apache 模块命令解析器原型
Apache module command parser prototype
我正在创建一个 Apache2 模块并遇到一个奇怪的编译问题。
这是我的函数原型,用于解析名为“analytics_ip”的配置命令:
static const char *apr_cfg_set_analytics_ip(cmd_parms *cmd, void *config, const char *data);
这是包含指向此函数的指针的 command_rec 结构数组:
static const command_rec apr_cmds[] =
{
AP_INIT_TAKE1("analytics_ip", apr_cfg_set_analytics_ip, NULL, OR_ALL, ""),
{ NULL }
};
头文件中声明了结构 command_rec http_config.h
typedef struct command_struct command_rec;
struct command_struct {
/** Name of this command */
const char *name;
/** The function to be called when this directive is parsed */
cmd_func func;
/** Extra data, for functions which implement multiple commands... */
void *cmd_data;
/** What overrides need to be allowed to enable this command. */
int req_override;
/** What the command expects as arguments */
enum cmd_how args_how;
/** 'usage' message, in case of syntax errors */
const char *errmsg;
};
当我按照cmd_func时,会得到如下声明:
typedef const char *(*cmd_func) ();
如果我没记错的话,意思是"pointer to function returning pointer to char and not accepting any arguments"。这怎么可能?命令解析函数必须接受至少一个参数,其中包含与该函数对应的配置变量的模块值。
我正在使用 g++ 编译这个模块。
错误信息:
mod_xxx.h:65:2: error: invalid conversion from ‘const char* (*)(cmd_parms*, void*, const char*) {aka const char* (*)(cmd_parms_struct*, void*, const char*)}’ to ‘cmd_func {aka const char* (*)()}’ [-fpermissive]
};
提前致谢
cmd_func
是一个联合,在http_config.h中定义如下:
typedef union {
/** function to call for a no-args */
const char *(*no_args) (cmd_parms *parms, void *mconfig);
/** function to call for a raw-args */
const char *(*raw_args) (cmd_parms *parms, void *mconfig,
const char *args);
/** function to call for a argv/argc */
const char *(*take_argv) (cmd_parms *parms, void *mconfig,
int argc, char *const argv[]);
/** function to call for a take1 */
const char *(*take1) (cmd_parms *parms, void *mconfig, const char *w);
/** function to call for a take2 */
const char *(*take2) (cmd_parms *parms, void *mconfig, const char *w,
const char *w2);
/** function to call for a take3 */
const char *(*take3) (cmd_parms *parms, void *mconfig, const char *w,
const char *w2, const char *w3);
/** function to call for a flag */
const char *(*flag) (cmd_parms *parms, void *mconfig, int on);
} cmd_func;
enum cmd_how args_how;
负责选择正确的函数版本。
它的开关处理位于server/config.c(在invoke_cmd
函数中)。
您似乎使用的是 "take1" 版本,对应 cmd->AP_TAKE1
或 cmd->take1
.
问题可能是 C 和 C++ 有 differences regarding the union initialization。 (AP_INIT_TAKE1
使用在 C++ 中不起作用的 { .take1=func }
语法)。
您必须以 C++ 兼容的方式初始化 static const command_rec apr_cmds
或将其移动到使用 C 编译的单独目标文件。或者,如果您不使用 C++,则只需使用 [=19= 编译].
对于我正在处理的项目,我们最终添加了一个强制转换以允许编译成功完成,代码似乎工作正常,因为它正确读取了配置文件中指定的值。以下是该实践的摘录:
extern "C" {
static const command_rec kiwix_settings[] =
{
AP_INIT_TAKE1("zimFile", (const char* (*)())kiwix_set_zimfilename, NULL, RSRC_CONF, "The ZIM filename in full including the extension"),
AP_INIT_TAKE1("zimPath", (const char* (*)())kiwix_set_path, NULL, RSRC_CONF, "The path to the ZIM file, including the trailing //"),
{ NULL }
};
}
完整文件(实际上是项目)是开源的。这是完整文件 https://github.com/kiwix/kiwix-apache/blob/master/mod_kiwix.cpp
的 link
PS:感谢您的问题和 https://whosebug.com/users/257568/artemgr 的回答,他们帮助我和另一位志愿者解决了我们项目的问题。
我正在创建一个 Apache2 模块并遇到一个奇怪的编译问题。 这是我的函数原型,用于解析名为“analytics_ip”的配置命令:
static const char *apr_cfg_set_analytics_ip(cmd_parms *cmd, void *config, const char *data);
这是包含指向此函数的指针的 command_rec 结构数组:
static const command_rec apr_cmds[] =
{
AP_INIT_TAKE1("analytics_ip", apr_cfg_set_analytics_ip, NULL, OR_ALL, ""),
{ NULL }
};
头文件中声明了结构 command_rec http_config.h
typedef struct command_struct command_rec;
struct command_struct {
/** Name of this command */
const char *name;
/** The function to be called when this directive is parsed */
cmd_func func;
/** Extra data, for functions which implement multiple commands... */
void *cmd_data;
/** What overrides need to be allowed to enable this command. */
int req_override;
/** What the command expects as arguments */
enum cmd_how args_how;
/** 'usage' message, in case of syntax errors */
const char *errmsg;
};
当我按照cmd_func时,会得到如下声明:
typedef const char *(*cmd_func) ();
如果我没记错的话,意思是"pointer to function returning pointer to char and not accepting any arguments"。这怎么可能?命令解析函数必须接受至少一个参数,其中包含与该函数对应的配置变量的模块值。
我正在使用 g++ 编译这个模块。 错误信息:
mod_xxx.h:65:2: error: invalid conversion from ‘const char* (*)(cmd_parms*, void*, const char*) {aka const char* (*)(cmd_parms_struct*, void*, const char*)}’ to ‘cmd_func {aka const char* (*)()}’ [-fpermissive]
};
提前致谢
cmd_func
是一个联合,在http_config.h中定义如下:
typedef union {
/** function to call for a no-args */
const char *(*no_args) (cmd_parms *parms, void *mconfig);
/** function to call for a raw-args */
const char *(*raw_args) (cmd_parms *parms, void *mconfig,
const char *args);
/** function to call for a argv/argc */
const char *(*take_argv) (cmd_parms *parms, void *mconfig,
int argc, char *const argv[]);
/** function to call for a take1 */
const char *(*take1) (cmd_parms *parms, void *mconfig, const char *w);
/** function to call for a take2 */
const char *(*take2) (cmd_parms *parms, void *mconfig, const char *w,
const char *w2);
/** function to call for a take3 */
const char *(*take3) (cmd_parms *parms, void *mconfig, const char *w,
const char *w2, const char *w3);
/** function to call for a flag */
const char *(*flag) (cmd_parms *parms, void *mconfig, int on);
} cmd_func;
enum cmd_how args_how;
负责选择正确的函数版本。
它的开关处理位于server/config.c(在invoke_cmd
函数中)。
您似乎使用的是 "take1" 版本,对应 cmd->AP_TAKE1
或 cmd->take1
.
问题可能是 C 和 C++ 有 differences regarding the union initialization。 (AP_INIT_TAKE1
使用在 C++ 中不起作用的 { .take1=func }
语法)。
您必须以 C++ 兼容的方式初始化 static const command_rec apr_cmds
或将其移动到使用 C 编译的单独目标文件。或者,如果您不使用 C++,则只需使用 [=19= 编译].
对于我正在处理的项目,我们最终添加了一个强制转换以允许编译成功完成,代码似乎工作正常,因为它正确读取了配置文件中指定的值。以下是该实践的摘录:
extern "C" {
static const command_rec kiwix_settings[] =
{
AP_INIT_TAKE1("zimFile", (const char* (*)())kiwix_set_zimfilename, NULL, RSRC_CONF, "The ZIM filename in full including the extension"),
AP_INIT_TAKE1("zimPath", (const char* (*)())kiwix_set_path, NULL, RSRC_CONF, "The path to the ZIM file, including the trailing //"),
{ NULL }
};
}
完整文件(实际上是项目)是开源的。这是完整文件 https://github.com/kiwix/kiwix-apache/blob/master/mod_kiwix.cpp
的 linkPS:感谢您的问题和 https://whosebug.com/users/257568/artemgr 的回答,他们帮助我和另一位志愿者解决了我们项目的问题。