Apache APR可移植运行库简介(3)

日期:2008年3月2日 作者: 查看:[大字体 中字体 小字体]
2)、另一方面,static能够控制变量和函数对于连接器的可见性。一个static变量或者函数,对于特定的编译单元来说总是本地范围的,这个范围在C语言中通常是指当前文件,超过这个范围的文件或者函数是不可以看到static变量和函数的,因此编译器也无法访问到这些变量和函数,它们对编译器是不可见的。因此内部函数是不允许被直接调用的,任何直接调用都导致“尚未定义”的错误。不过潜在的好处就是,内部函数的修改不影响API接口。
static的这两种用法APR中都存在,但是第二种用法较多。
1.5.2.2外部API函数
对于APR用户而言,它们能够调用的只能是APR提供的API。要识别APR中提供的API非常的简单,如果函数是外部API,那么它的返回值总是用APR_DECLARE或者APR_DECLARE_NONSTD进行包装,比如:
APR_DECLARE(apr_hash_t *) apr_hash_make(apr_pool_t *pool);
APR_DECLARE(int) apr_fnmatch_test(const char *pattern);
APR_DECLARE和APR_DECLARE_NONSTD是两个宏定义,它们在apr.h中定义如下:
#define APR_DECLARE(type)            type
#define APR_DECLARE_NONSTD(type)     type
APR_DECLARE和APR_DECLARE_NONSTD到底是什么意思呢?为什么要将返回类型封装为宏呢?在apr.h中有这样的解释:
/**
 * The public APR functions are declared with APR_DECLARE(), so they may
 * use the most appropriate calling convention. Public APR functions with
 * variable arguments must use APR_DECLARE_NONSTD().
 *
 * @remark Both the declaration and implementations must use the same macro.
 * @example
 */
/** APR_DECLARE(rettype) apr_func(args)
 * @see APR_DECLARE_NONSTD @see APR_DECLARE_DATA
 * @remark Note that when APR compiles the library itself, it passes the
 * symbol -DAPR_DECLARE_EXPORT to the compiler on some platforms (e.g. Win32)
 * to export public symbols from the dynamic library build.\n
 * The user must define the APR_DECLARE_STATIC when compiling to target
 * the static APR library on some platforms (e.g. Win32.) The public symbols
 * are neither exported nor imported when APR_DECLARE_STATIC is defined.\n
 * By default, compiling an application and including the APR public
 * headers, without defining APR_DECLARE_STATIC, will prepare the code to be
 * linked to the dynamic library.
 */
#define APR_DECLARE(type)            type
/**
 * The public APR functions using variable arguments are declared with
 * APR_DECLARE_NONSTD(), as they must follow the C language calling convention.
 * @see APR_DECLARE @see APR_DECLARE_DATA
 * @remark Both the declaration and implementations must use the same macro.
 * @example
 */
/** APR_DECLARE_NONSTD(rettype) apr_func(args, ...);
 */
#define APR_DECLARE_NONSTD(type)     type
从上面的解释中我们可以看出“APR的固定个数参数公共函数的声明形式APR_DECLARE(rettype) apr_func(args);而非固定个数参数的公共函数的声明形式为APR_DECLARE_NONSTD(rettype) apr_func(args, ...);”。
在apr.h文件中解释了这么做就是为了在不同平台上编译时使用“the most appropriate calling convention”,这里的“calling convention”是一术语,翻译过来叫“调用约定”。 我们知道函数调用是通过栈操作来完成的,在栈操作过程中需要函数的调用者和被调用者在下面的两个问题上做出协调,达成协议:
a) 当参数个数多于一个时,按照什么顺序把参数压入堆栈
b) 函数调用后,由谁来把堆栈恢复原来状态
c) 产生函数修饰名的方法
在像C/C++这样的中、高级语言中,使用“调用约定”来说明这两个问题。常见的调用约定有:__stdcall、__cdecl、__fastcall、thiscall和naked call。
__stdcall调用约定:函数的参数自右向左通过栈传递,被调用的函数在返回前清理传送参数的内存栈。
__cdecl是C和C++程序的缺省调用方式。每一个调用它的函数都包含清空堆栈的代码,所以产生的可执行文件大小会比调用_stdcall函数的大。函数采用从右到左的压栈方式。注意:对于可变参数的成员函数,始终使用__cdecl的转换方式
__fastcall调用约定规定通过寄存器来传送参数的(实际上,它用ECX和EDX传送前两个双字(DWORD)或更小的参数,剩下的参数仍旧自右向左压栈传送,被调用的函数在返回前清理传送参数的内存栈)。
thiscall仅仅应用于"C++"成员函数。this指针存放于CX寄存器,参数从右到左压。thiscall不是关键词,因此不能被程序员指定。
naked call采用上述调用约定时,如果必要的话,进入函数时编译器会产生代码来保存ESI,EDI,EBX,EBP寄存器,退出函数时则产生代码恢复这些寄存器的内容。naked call不产生这样的代码。naked call不是类型修饰符,故必须和_declspec共同使用。
另外不同的调用约定对于函数内部修饰名处理的方法也不一样。所谓修饰名是C或者C++函数在内部编译和链接的时候产生的唯一的标识名称。
对于C语言而言,__stdcall调用约定在输出函数名前加上一个下划线前缀,后面加上一个"@"符号和其参数的字节数,格式为_functionname@number,例如 :function(int a, int b),其修饰名为:_function@8
__cdecl调用约定仅在输出函数名前加上一个下划线前缀,格式为_functionname。
__fastcall调用约定在输出函数名前加上一个"@"符号,后面也是一个"@"符号和其参数的字节数,格式为@functionname@number。
如果是C++,不同调用约定处理要稍微复杂一点。由于Apache是基于C语言开发,因此本处不再描述。
1.5.2.3内存池参数
关于函数的最后一个问题就是它的参数,如果函数内部需要分配空间,那么你就可以看到参数的参数中肯定包含一个apr_pool_t参数,比如:
APR_DECLARE(apr_status_t) apr_shm_attach(apr_shm_t **m,
                                         const char *filename,
                                         apr_pool_t *pool);
由于Apache服务器所具有的一些特性,APR中并没有使用普通的malloc/free内存管理策略,而是使用了自行设计的内存池管理策略。APR中所有的需要的内存都不再直接使用malloc分配,然后首先分配一块足够大的内存块,然后每次需要的时候再从中获取;当内存不再使用的时候也不是直接调用free,而是直接归还给内存池。只有当内存池本身被释放的时候,这些内存才真正的被free给操作系统。Apache中使用apr_pool_t描述一个内存池,因此毫无疑问,由于这种特殊的内存分配策略,对于任何一个函数,如果你需要使用内存,那么你就应该指定内存所源自的内存池。这就是为什么大部分函数参数中都具有apr_pool_t的原因。关于内存池的详细细节,我们在第二章详细讨论。
  • 上一页 [1] [2] [3] 下一页 


  • Apache APR可移植运行库简介(3) 相关文章:
  • ·掌握SQL Server数据库的实用技巧
  • ·Oracle非法数据库对象引起的错误
  • ·SuSE Linux10上安装Oracle数据库方法
  • ·缩小SQL Server数据库的日志文件
  • ·用SQL链接服务器访问远程Access数据库
  • ·平面设计中字库使用的问题解答
  • ·使用重定向恢复DB2数据库
  • ·浅谈DB2数据库故障处理及最佳实践
  • ·T-SQL语句实现数据库备份与还原
  • ·Java语言数据库操作的基本流程
  • Apache APR可移植运行库简介(3) 相关软件
  • ·《黑名单上的人》02夜袭车库(198209版)
  • ·《仓库番》试玩脑细胞杀手
  • ·美术欣赏-中国画经典图库.part1
  • ·《英诗金库(The Golden Treasury)》
  • ·《少儿文学名著文库》V1.0
  • ·判决案例全库v1.0
  • ·世界金奖童话库
  • ·四库全书v2.0(压缩卷3-1)
  • ·数据库营销
  • ·vc模板库手册
  • 上一篇:gsoap中文文档(8.1.1)

    下一篇:Apache APR可移植运行库简介(1)

  • 特别声明:本站除部分特别声明禁止转载的专稿外的其他文章可以自由转载,但请务必注明出处和原始作
  • 者.文章版权归文章原始作者所有.对于被本站转载文章的个人和网站,我们表示深深的谢意。如果本站转
  • 载的文章有版权问题请联系编辑人员,我们尽快予以更正. 转载请注明来源:http://www.hackhome.com
  • 精品推荐

    热点TOP10

    特别推荐