#define的妙用|do...while(0)|函数指针提高程序的可维护性|手动加载动态链接库

来源:互联网 发布:螳螂 知乎 编辑:程序博客网 时间:2024/06/08 05:23

一、#define的妙用


1. 在大规模的开发过程中,特别是跨平台和系统的软件里,define最重要的功能是条件编译。

2. 注意事项 只是简单的字串替换


#define MIN(a,b)  a < b ? a : b     // WRONG

int i = MIN(1,2); // works
int i = MIN(1,1+1); // breaks

#define MIN(a,b)  (a) < (b) ? (a) : (b)   // STILL WRONG

int i = MIN(1,2); // works
int i = MIN(1,1+1); // now works
int i = MIN(1,2) + 1; // breaks

#define MIN(a,b)  ((a) < (b) ? (a) : (b))   // GOOD :)

int i = MIN(1,2); // works
int i = MIN(1,1+1); // now works
int i = MIN(1,2) + 1; // works

However, MIN(3,i++) is still broken...

二、do...while(0)


能实现复杂的定义,并且通用性很强。

...

#define DOIT(x)  do{x }while(0)


三、函数指针提高程序的可维护性


对降低程序耦合度,提高代码独立性,可维护性,模块化起重要作用。

四、手动加载动态链接库


1.  打开动态链接库:
    #include <dlfcn.h>
    void *dlopen(const char *filename, int flag);
    该函数返回操作句柄 ,如:
    void *pHandle = dlopen(strSoFilePath, RTLD_LAZY);

2.  取动态对象地址:
    #include <dlfcn.h>
    void *dlsym(void *pHandle, char *symbol);
    dlsym根据动态链接库操作句柄 (pHandle)与符号 (symbol),返回符号对应的地址。
    使用这个函数不但可以获取函数地址,也可以获取变量地址。比如,假设在so中
    定义了一个void mytest()函数,那在使用so时先声明一个函数指针:
    void (*pMytest)(),然后使用dlsym函数将函数指针pMytest指向mytest函数,
    pMytest = (void (*)())dlsym(pHandle, "mytest");

3.  关闭动态链接库:
    #include <dlfcn.h>
    int dlclose(void *handle);
    该函数将该.so的引用计数减一,当引用计数为0时,将它从系统中卸载。

4.  动态库错误函数:
    #include <dlfcn.h>
    const char *dlerror(void);
    当动态链接库操作函数执行失败时,dlerror可以返回出错信息,返回值为NULL时
    表示没有错误信息。

    在取到函数执行地址后,就可以在动态库的使用程序里根据动态库提供的函数接口
    调用动态库里的函数。
    在编写调用动态库的程序的Makefile文件时,需要加入编译选项-ldl。

    从void *dlsym(void *handle, char *symbol); 的参数可以看出,该函数只传两个
    参数:一个指向so的handle和一个函数的symbol,所以so里面的函数应该不允许重载,
    否则根据一个 symbol不能确定指向那个函数。


参考

http://hi.baidu.com/henfengduandie/blog/item/09d78d35a91eac93a71e1282.html

原创粉丝点击