跨平台编程是个很有意思的工作,研究Apache的架构有段时间了,对他跨平台的手段有一定的理解.
Apache跨平台的基础主要分为2种情况,一种是不同的操作系统,另外一种是不同不同编译器.在Apache有少部分的代码是和汇编指令有关的,这部分只占很少的一部分,而且主要是集中在APR库中,比如ATOMIC代码,基于代码效率考虑,有些是直接使用汇编代码的.
下面我们主要集中介绍Apache跨平台所使用的一些技巧:
1.预声明,将具体定义延后到与平台相关的文件中.
如apr_dso.h / apr_arch_dso.h / dso.c三个文件之间的关系很明显的反映这种关系.
在apr_dso.h中,预声明了typedef struct apr_dso_handle_t apr_dso_handle_t;但是struct apr_dso_hande_t的具体结构并没有在apr_dso.h中出现,但apr_dso.h中提供对apr_dso_handle_t的操作.
在win32/apr_arch_dso.h中定义了
struct apr_dso_handle_t {
apr_pool_t *cont;
void *handle;
apr_status_t load_error;
};
但在unix/apr_arch_dso.h中定义了
struct apr_dso_handle_t {
apr_pool_t *pool;
void *handle;
const char *errormsg;
};
这些和平台相关的特性放置在不同的文件中,在不同的平台下,通过选择不同的文件,可以正确得实现平台相关特性.xxx_arch_xxx和x.c是匹配使用的.但对使用者来说,他只要关心apr_dso.h提供的接口就可以了.
2.用结构不同的属性进行打包.包含不同平台需要的信息.
在apr_file_info.h中定义了文件信息结构:
struct apr_finfo_t {
/** Allocates memory and closes lingering handles in the specified pool */
apr_pool_t *pool;
/** The bitmask describing valid fields of this apr_finfo_t structure
* including all available 'wanted' fields and potentially more */
apr_int32_t valid;
/** The access permissions of the file. Mimics Unix access rights. */
apr_fileperms_t protection;
/** The type of file. One of APR_REG, APR_DIR, APR_CHR, APR_BLK, APR_PIPE,
* APR_LNK or APR_SOCK. If the type is undetermined, the value is APR_NOFILE.
* If the type cannot be determined, the value is APR_UNKFILE.
*/
apr_filetype_e filetype;
/** The user id that owns the file */
apr_uid_t user;
/** The group id that owns the file */
apr_gid_t group;
/** The inode of the file. */
apr_ino_t inode;
/** The id of the device the file is on. */
apr_dev_t device;
/** The number of hard links to the file. */
apr_int32_t nlink;
/** The size of the file */
apr_off_t size;
/** The storage size consumed by the file */
apr_off_t csize;
/** The time the file was last accessed */
apr_time_t atime;
/** The time the file was last modified */
apr_time_t mtime;
/** The time the file was created, or the inode was last changed */
apr_time_t ctime;
/** The pathname of the file (possibly unrooted) */
const char *fname;
/** The file's name (no path) in filesystem case */
const char *name;
/** The file's handle, if accessed (can be submitted to apr_duphandle) */
struct apr_file_t *filehand;
};
这个结构所包含的信息和平台都没有关系,通过不同平台的x.c文件来完成对这个值的填充.这种方式主要针对不同平台之间,相同或者相似的功能,但是实现方式确完成不同的情况,比如文件.
主要通过这两种方式,APR为不同平台实现跨平台的函数接口
Apache跨平台的基础主要分为2种情况,一种是不同的操作系统,另外一种是不同不同编译器.在Apache有少部分的代码是和汇编指令有关的,这部分只占很少的一部分,而且主要是集中在APR库中,比如ATOMIC代码,基于代码效率考虑,有些是直接使用汇编代码的.
下面我们主要集中介绍Apache跨平台所使用的一些技巧:
1.预声明,将具体定义延后到与平台相关的文件中.
如apr_dso.h / apr_arch_dso.h / dso.c三个文件之间的关系很明显的反映这种关系.
在apr_dso.h中,预声明了typedef struct apr_dso_handle_t apr_dso_handle_t;但是struct apr_dso_hande_t的具体结构并没有在apr_dso.h中出现,但apr_dso.h中提供对apr_dso_handle_t的操作.
在win32/apr_arch_dso.h中定义了
struct apr_dso_handle_t {
apr_pool_t *cont;
void *handle;
apr_status_t load_error;
};
但在unix/apr_arch_dso.h中定义了
struct apr_dso_handle_t {
apr_pool_t *pool;
void *handle;
const char *errormsg;
};
这些和平台相关的特性放置在不同的文件中,在不同的平台下,通过选择不同的文件,可以正确得实现平台相关特性.xxx_arch_xxx和x.c是匹配使用的.但对使用者来说,他只要关心apr_dso.h提供的接口就可以了.
2.用结构不同的属性进行打包.包含不同平台需要的信息.
在apr_file_info.h中定义了文件信息结构:
struct apr_finfo_t {
/** Allocates memory and closes lingering handles in the specified pool */
apr_pool_t *pool;
/** The bitmask describing valid fields of this apr_finfo_t structure
* including all available 'wanted' fields and potentially more */
apr_int32_t valid;
/** The access permissions of the file. Mimics Unix access rights. */
apr_fileperms_t protection;
/** The type of file. One of APR_REG, APR_DIR, APR_CHR, APR_BLK, APR_PIPE,
* APR_LNK or APR_SOCK. If the type is undetermined, the value is APR_NOFILE.
* If the type cannot be determined, the value is APR_UNKFILE.
*/
apr_filetype_e filetype;
/** The user id that owns the file */
apr_uid_t user;
/** The group id that owns the file */
apr_gid_t group;
/** The inode of the file. */
apr_ino_t inode;
/** The id of the device the file is on. */
apr_dev_t device;
/** The number of hard links to the file. */
apr_int32_t nlink;
/** The size of the file */
apr_off_t size;
/** The storage size consumed by the file */
apr_off_t csize;
/** The time the file was last accessed */
apr_time_t atime;
/** The time the file was last modified */
apr_time_t mtime;
/** The time the file was created, or the inode was last changed */
apr_time_t ctime;
/** The pathname of the file (possibly unrooted) */
const char *fname;
/** The file's name (no path) in filesystem case */
const char *name;
/** The file's handle, if accessed (can be submitted to apr_duphandle) */
struct apr_file_t *filehand;
};
这个结构所包含的信息和平台都没有关系,通过不同平台的x.c文件来完成对这个值的填充.这种方式主要针对不同平台之间,相同或者相似的功能,但是实现方式确完成不同的情况,比如文件.
主要通过这两种方式,APR为不同平台实现跨平台的函数接口