ap_hook_handler的定义在哪?

ap_config.h 文件里有定义

/**
* Declare a hook function
* @param ret The return type of the hook
* @param name The hook’s name (as a literal)
* @param args The arguments the hook function takes, in brackets.
*/
#define AP_DECLARE_HOOK(ret,name,args)
APR_DECLARE_EXTERNAL_HOOK(ap,AP,ret,name,args)

 

近日在看apache的源码,在他的module的定义中,ap_hook_handler是一个非常重要的函数。用来在apache中注册你的自定义module中的callback函数。

遍搜ap_hook_handler,寻不得在哪定义的。最后发现,这家伙把所有的hook函数都定义在宏里。比代码混淆都NB。作为一个长期从事.net开发的人而言,可称得上变态了。

A:

AP_DECLARE_HOOK(int,handler,(request_rec *r))

B:

#define AP_DECLARE_HOOK(ret,name,args) APR_DECLARE_EXTERNAL_HOOK(ap,AP,ret,name,args)

C:

#define APR_DECLARE_EXTERNAL_HOOK(ns,link,ret,name,args)

D:

typedef ret ns##_HOOK_##name##_t args;

link##_DECLARE(void) ns##_hook_##name(ns##_HOOK_##name##_t *pf,

const char * const *aszPre,

const char * const *aszSucc, int nOrder);

link##_DECLARE(ret) ns##_run_##name args;

APR_IMPLEMENT_HOOK_GET_PROTO(ns,link,name);

typedef struct ns##_LINK_##name##_t

{

ns##_HOOK_##name##_t *pFunc;

const char *szName;

const char * const *aszPredecessors;

const char * const *aszSuccessors;

int nOrder;

} ns##_LINK_##name##_t;

E:

#define AP_DECLARE(type)            type

F:

#define APR_IMPLEMENT_HOOK_GET_PROTO(ns,link,name)

link##_DECLARE(apr_array_header_t *) ns##_hook_get_##name(void)

 

把A套入B,得到:

ns = ap
name = handler
arg = (request_rec *r)

把B套入C,又得到:

link = AP

把C套入D,再加上E中的声明, 最终得到:

typedef int ap_HOOK_handler_t (request_rec *r);

void ap_hook_handler(ap_HOOK_handler_t *pf, char * const *aszPre, char * const *aszSucc, int nOrder);

int ap_run_handler (request_rec *r);

APR_IMPLEMENT_HOOK_GET_PROTO(ap,AP,handler);

typedef struct ap_LINK_handler_t

{

ap_HOOK_handler_t *pFunc;

const char *szName;

const char * const *aszPredecessors;

const char * const *aszSuccessors;

int nOrder;

} ap_LINK_handler_t;

 

其实到这里,我已经看到了ap_hook_handler的声明。因此才得以合法的调用ap_hook_handler。一切来源于代码A,A中的一行,最终会被替代成一堆struct定义和函数声明。让我们继续挖一下,把他完全展开,将F也套入APR_IMPLEMENT_HOOK_GET_PROTO(ap,AP,handler);,得到:

typedef int ap_HOOK_handler_t (request_rec *r);

void ap_hook_handler(ap_HOOK_handler_t *pf, char * const *aszPre, char * const *aszSucc, int nOrder);

int ap_run_handler (request_rec *r);

apr_array_header_t * ap_hook_get_handler(void);

typedef struct ap_LINK_handler_t

{

ap_HOOK_handler_t *pFunc;

const char *szName;

const char * const *aszPredecessors;

const char * const *aszSuccessors;

int nOrder;

} ap_LINK_handler_t;

 

感谢netbeans,在Linux下,着实除了他,别的工具真的很难挖出这个大萝卜。

 

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>