Error of "Undefined reference to: XXX"...
Labels: link
Labels: link
项目需要,而且网上的中英文材料都语焉不详,所以看了看apache hooks的代码。
我们的代码是:
static void register_hooks(apr_pool_t *pool) {
...
ap_hook_translate_name(set_cookie, NULL, NULL, APR_HOOK_FIRST);
ap_hook_handler(process_request, NULL, NULL, APR_HOOK_FIRST);
}
module another_client = {
...;
register_hooks;
};
我想搞明白来一个request,到底cookie是怎么handle的,所以需要知道到底set_cookie和process_request的调用的order到底是怎样的。好了,然后这个问题看了我快一天,这代码写的。
首先是ap_hook_translate_name(...)。这个的函数是有宏写的定义,方便扩展到自定义的hooks上。(我不是很确定这是一种很现代化的实现,不过在那个用C来写可扩展程序的年代,貌似也是一种唯一的办法了)下面是我手动扩展出来的定义代码:(你也可以用-E的选项生成语编译代码来看看是否是你需要的东西,定义在include/http_request.h,实现在server/request.c)
// Declaration
typedef int ap_HOOK_translate_name_t (request_rec *r);
void ap_hook_translate_name(ap_HOOK_translate_name_t *pf,
const char * const *aszPre,
const char * const *aszSucc, int nOrder);
int ap_run_translate_name (request_rec *r);
apr_array_header_t * ap_hook_get_translate_name(void)
typedef struct ap_LINK_translate_name_t {
ap_HOOK_translate_name_t *pFunc;
const char *szName;
const char * const *aszPredecessors;
const char * const *aszSuccessors;
int nOrder;
} ap_LINK_translate_name_t;
// Implementation
void ap_hook_translate_name(
ap_HOOK_translate_name_t *pf,
const char * const *aszPre,
const char * const *aszSucc,
int nOrder)
{
ap_LINK_translate_name_t *pHook;
if(!_hooks.link_translate_name)
{
_hooks.link_translate_name = apr_array_make(
apr_hook_global_pool,1,sizeof(ap_LINK_translate_name_t));
apr_hook_sort_register(translate_name,
&_hooks.link_translate_name);
}
pHook=apr_array_push(_hooks.link_translate_name);
pHook->pFunc=pf;
pHook->aszPredecessors=aszPre;
pHook->aszSuccessors=aszSucc;
pHook->nOrder=nOrder;
pHook->szName=apr_hook_debug_current;
if(apr_hook_debug_enabled)
apr_hook_debug_show(translate_name, aszPre, aszSucc);
}
apr_array_header_t * ap_hook_get_translate_name(void)
{
return _hooks.link_translate_name;
}
int ap_run_translate_name (request_rec *r)
{
ap_LINK_translate_name_t *pHook;
int n;
int rv;
if(!_hooks.link_translate_name)
return DECLINED;
pHook=(ap_LINK_translate_name_t *)_hooks.link_translate_name->elts;
for(n=0 ; n < _hooks.link_translate_name->nelts ; ++n)
{
rv=pHook[n].pFunc (r);
if(rv != DECLINED)
return rv;
}
return DECLINED;
}
可以看出来,调用translate_name的hook的入口是ap_run_translate_name。然后我们就可以关注到底那里调用了这个东西,以及另外ap_run_handler的位置在哪里了。这个任务相对比较简单,它们的位置分别是modules/http/http_request.c中的ap_process_request(...)和server/request.c中的ap_process_request_internal(...),下面是我根据这两个函数summarize出来的我所知道的所有hooks的order:
Read more »
不知道是我太久没写了,还是coding style和C++的指针传递太危险了,编译和lint一直有问题。写程序花了2小时,让它编译通过花了6个小时,恐怕有重新学习C++的危险了。
下面举个例子:
hash_map<string, string=""> properties;
...
for (hash_map<string, string="">::const_iterator
ii = properties.begin(); ii != properties.end(); ++ii) {
LOG(INFO) << (ii->first) << " = " << (ii->second) << std:endl;
}
这不是一个很简单的code吗,结果死活编译不过去!爬到源码堆里一看,原来g++ 3.4 是这么定义的:
namespace __gnu_cxx {
template <class _Key, class _Tp, class _HashFcn = hash<_Key>,
class _EqualKey = equal_to<_Key>, class _Alloc = allocator<_Tp> >
class hash_map;
也就是说,你写一个hash_map<string, string>啥的的话,它回去lookup下面三个函数对象(是不是这个名字阿?):
struct hash<string> { // just for simplication, in STL, it is basic_string
size_t operator()(string s) const {...}
};
struct equal_to<string> {...};
struct allocator<string> {...};
然后我看了一下在hash_fun.h里的定义,就悲剧了!原来只有hash<const char *>。
所以,同学们,写C++的话,不会看源代码,大约只能等死了。而且,熟悉它的话,恐怕要花点时间,譬如说半年。当然,现在有些库已经挺好用的了,特别是boost。所以,你还是很有机会在很熟悉的情况下用的挺好的的。
至于我,我觉着language应该需要有些进步了,否则真的太浪费engineer的时间了。特别是好多C++ coding style方面的限制,真的就是用来防止函数副作用的而已。但是已经搞得写code和读code都不是那么方便了。
写code,应该和写文章一样让人有赏心悦目的感觉!