设为首页 收藏本站
查看: 692|回复: 0

[经验分享] [转载] Apache模块开发/用C语言扩展apache(2:APR编程介绍)

[复制链接]

尚未签到

发表于 2017-1-7 11:09:41 | 显示全部楼层 |阅读模式
  可以看到apache代码中使用了大量的以apr_开头的结构或者函数,这些其实是APR.
  什么是apr?
  我的理解是apache工作小组在编写apache等C程序过程中所积累的一套编程框架, 里面提供比较先进的内存管理模式和常用的数据结构,另外根据各种平台作了一些不同的宏定义,让代码做到平台无关性。由于做得不错,后来,就干脆把它从apache源代码中脱离出来,又搞了一个项目,apache官方站点上也有它的相关介绍:http://apr.apache.org/
  The mission of the Apache Portable Runtime (APR) project is to create and maintain software libraries that provide a predictable and consistent interface to underlying platform-specific implementations. The primary goal is to provide an API to which software developers may code and be assured of predictable if not identical behaviour regardless of the platform on which their software is built, relieving them of the need to code special-case conditions to work around or take advantage of platform-specific deficiencies or features.
  apr可以独立于apache安装,让我们编写应用程序时也使用。
  有个非常好的英文文档介绍了怎么样使用:http://dev.ariel-networks.com/ap ... l/apr-tutorial.html
  上面那个文档非常不错,大家看懂了,我写的这篇就不用看了。
  我这个把几个以后经常要用到的介绍一下。
  (1) apr_pool_t *pool
  内存池,所有的内存操作可以基于这个池之上,当这个池不再需要时,一次性释放该池上的所有内存,这个模式非常适合基于session服务的编程模式, 比如:每个http request都分配一个apr_pool_t,当该http request end时,一次性释放该request运行时申请的所有内存。可以看到struct request_rec中就有这个东东。
  用法:


apr_pool_t *mp;
apr_pool_create(&mp, NULL);

char *buf1;
buf1 = apr_palloc(mp, MEM_ALLOC_SIZE);
apr_pool_t *mp;
apr_pool_create(&mp, NULL);
for (i = 0; i < n; ++i) {
do_operation(..., mp);
apr_pool_clear(mp);
}
apr_pool_destroy(mp);
   (2)数据结构--容器
  动态数组---apr_array_header_t
  类似于hashmap的apr_table_t:
  apr_table_t *tab;
  tab = apr_table_make(mp, 5);
  apr_table_setn(tab, "foo", "bar");
  apr_table_setn(tab, apr_pstrdup(mp, "foo"), apr_pstrdup(mp, "bar"));
  const char *v = apr_table_get(tab, "mykey");
  可以看到apr_table_t存储key-value pairs类型的数据非常方便,难怪apache所有的http header都用它存储。
  其他操作apr_table_t的函数:


APR_DECLARE(const apr_array_header_t *) apr_table_elts(const apr_table_t *t);

APR_DECLARE(int) apr_is_empty_table(const apr_table_t *t);

APR_DECLARE(int) apr_is_empty_array(const apr_array_header_t *a);

APR_DECLARE(apr_array_header_t *) apr_array_make(apr_pool_t *p,
int nelts, int elt_size);

APR_DECLARE(void *) apr_array_push(apr_array_header_t *arr);

APR_DECLARE(void *) apr_array_pop(apr_array_header_t *arr);

APR_DECLARE(void) apr_array_cat(apr_array_header_t *dst,
const apr_array_header_t *src);

APR_DECLARE(apr_array_header_t *) apr_array_copy(apr_pool_t *p,
const apr_array_header_t *arr);
APR_DECLARE(apr_array_header_t *) apr_array_copy_hdr(apr_pool_t *p,
const apr_array_header_t *arr);

APR_DECLARE(apr_array_header_t *) apr_array_append(apr_pool_t *p,
const apr_array_header_t *first,
const apr_array_header_t *second);

APR_DECLARE(char *) apr_array_pstrcat(apr_pool_t *p,
const apr_array_header_t *arr,
const char sep);

APR_DECLARE(apr_table_t *) apr_table_make(apr_pool_t *p, int nelts);

APR_DECLARE(apr_table_t *) apr_table_copy(apr_pool_t *p,
const apr_table_t *t);

APR_DECLARE(void) apr_table_clear(apr_table_t *t);

APR_DECLARE(const char *) apr_table_get(const apr_table_t *t, const char *key);

APR_DECLARE(void) apr_table_set(apr_table_t *t, const char *key,
const char *val);

APR_DECLARE(void) apr_table_setn(apr_table_t *t, const char *key,
const char *val);

APR_DECLARE(void) apr_table_unset(apr_table_t *t, const char *key);

APR_DECLARE(void) apr_table_merge(apr_table_t *t, const char *key,
const char *val);

APR_DECLARE(void) apr_table_mergen(apr_table_t *t, const char *key,
const char *val);

APR_DECLARE(void) apr_table_add(apr_table_t *t, const char *key,
const char *val);

APR_DECLARE(void) apr_table_addn(apr_table_t *t, const char *key,
const char *val);

APR_DECLARE(apr_table_t *) apr_table_overlay(apr_pool_t *p,
const apr_table_t *overlay,
const apr_table_t *base);

typedef int (apr_table_do_callback_fn_t)(void *rec, const char *key,
const char *value);

APR_DECLARE_NONSTD(int) apr_table_do(apr_table_do_callback_fn_t *comp,
void *rec, const apr_table_t *t, ...);

APR_DECLARE(int) apr_table_vdo(apr_table_do_callback_fn_t *comp,
void *rec, const apr_table_t *t, va_list vp);

#define APR_OVERLAP_TABLES_SET   (0)
#define APR_OVERLAP_TABLES_MERGE (1)

APR_DECLARE(void) apr_table_overlap(apr_table_t *a, const apr_table_t *b,
unsigned flags);

APR_DECLARE(void) apr_table_compress(apr_table_t *t, unsigned flags);
   其他apr提供的数据结构还有:hash和list,这里不再详述。
  (3) 字符串操作
  写过C的人都知道,处理字符串是非常头痛的问题,搞不好就内存溢出,apr也提供一些字符串函数,都是基于apr_pool_t, 使用时不用担心内存溢出的问题。
  把apr_strings.h贴出来大家一起看看,注释也比较详细,不多说:


APR_DECLARE(int) apr_strnatcmp(char const *a, char const *b);

APR_DECLARE(int) apr_strnatcasecmp(char const *a, char const *b);

APR_DECLARE(char *) apr_pstrdup(apr_pool_t *p, const char *s);

APR_DECLARE(char *) apr_pstrmemdup(apr_pool_t *p, const char *s, apr_size_t n);

APR_DECLARE(char *) apr_pstrndup(apr_pool_t *p, const char *s, apr_size_t n);

APR_DECLARE(void *) apr_pmemdup(apr_pool_t *p, const void *m, apr_size_t n);

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-325050-1-1.html 上篇帖子: Java用apache的HttpClient发送Post请求 下篇帖子: 切记版本对应:记apache resin整合折腾记
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表