【C语言】【unix c】动态加载

来源:互联网 发布:教务系统数据库表 编辑:程序博客网 时间:2024/06/16 02:25
动态加载:    在程序中根据程序的需要,动态加载某个库函数,这种行为称为动态加载,系统为实现动态加载提供了一下函数:        man 3 dlopen显示帮助:           头文件:#include <dlfcn.h>               void *dlopen(const char *filename, int flag);                功能:加载一个动态库文件,返回一个地址                参数:                    filename:制定了动态库的文件名字                    flag:                        RTLD_LAZY:懒加载                        RTLD_NOW:立即加载                返回值:失败的时候返回NULL,成功的时候返回一个指针               char *dlerror(void);                功能:获取dlopen,dlclose,slsym函数产生的错误                参数:无                返回值:返回一个字符串,这个字符串描述了错误的原因               void *dlsym(void *handle, const char *symbol);                功能:在内存查找动态库中的symbal加载到内存的地址                参数:                    handle:dlopen(3)的返回值,制定了要操作的库函数                    symbol:制定了要着的符号                返回值:返回NULL:代表错误, 返回symbol加载到的内存的地址               int dlclose(void *handle);                功能:将与handle相关的动态库文件的引用计数减1,库文件的引用计数减到0的时候,动态库从内存中移除                参数:                    handle:制定了要关闭的动态库,是dkopen(3)的返回值                返回值:非0代表错误,0代表成功            注意:Link with -ldl.//在GCC后面加上 -ldl                举例说明:将libpmath.so动态库加载到内存,并使用函数库中的函数(dynamic.c)                    #include <stdio.h>                    #include <dlfcn.h>                    typedef int (*func_t) (int,int);                     int main(void) {                        //加载动态库                        void *handle = dlopen("libpmath.so", RTLD_NOW);//这个函数是传入一个动态库文件的名字(字符串)和一个标示(见上面笔记),返回的是void *,也就是一个指针                        if(handle == NULL) {                        //printf("dlopen failed...\n");                        printf("%s\n", dlerror());//将错误信息输出,dlerror                        return 0;                        }                        printf("dlopen success...\n");                        //在内存中查找函数的入口地址                        void *f = dlsym(handle, "t_add");                        if(f == NULL) {                        printf("%s\n", dlerror());                        }                        func_t p = (func_t)f;  //func_t p = (int (*) (int,int))f 也可以                        printf("3+2=%d\n", p(3,2));                        //关闭动态库                        dlclose(handle);                        return 0;                    }                    测试dlopen,dlclose函数:                        tarena@ubuntu:~/day/day25$ gcc dynamic.c -ldl                        tarena@ubuntu:~/day/day25$ a.out                         dlopen success...                    测试dlerror函数:                        tarena@ubuntu:~/day/day25$ a.out                         libpath.so: cannot open shared object file: No such file or directory                    测试dlsym函数:                        tarena@ubuntu:~/day/day25$ gcc dynamic.c -ldl                        tarena@ubuntu:~/day/day25$ a.out                         dlopen success...                        3+2=5