Linux下C编程使用动态链接库

为了方便程序功能的后期升级扩展,在程序设计时经常会用到动态库,这样子程序只有到运行阶段才会去加载动态库并且使用库中的函数,那么我们往往只需要更新DLLWindows系统)或SOLinux系统)文件即可达到,同时打包成库也有利于保密和核心技术的积累,话不多说,接下来看看Linux下的动态链接库相关内容:1.头文件及编译选项
Linux下对so动态链接库进行操作时,需#include <dlfcn.h>,将dlfcn.h头文件包含进来,并且在使用gcc编译时要使用-ldl选项。
2.常用函数
a.void *dlopen(const char *filename, int flag); 其中,函数返回动态库的操作Handle(句柄),filename为库名,而flag常用的值有如下两个(必须使用其中一个,其他标志可使用man dlopen查看):
RTLD_LAZY:在打开SO时不对共享库的函数进行加载操作,等到dlsym调用时才加载指定函数;
RTLD_NOW:在打开SO时将共享库的所有函数加载至内存。
b.void *dlsym(void *handle, const char *symbol); dlopen返回的handle里找名为symbol的函数指针并将其返回,注意这里返回的是void *,须做类型转换。
c.int dlclose(void *handle); 关闭dlopen打开的Handle
d.char *dlerror(void); 当上述动态链接库操作函数被调用后,再调用本函数时,返回NULL表示没有错误发生,如果有错误发现,其将返回一个错误字符串,即出错信息。
3.如何查找库 这里忽略ELF文件里的DT_RPATHDT_RUNPATH标志时的情况,下面是标准的查找库顺序:
首先查找
LD_LIBRARY_PATH环境变量对应的目录,找不到时再查找/etc/ld.so.cache文件(由ldconfig命令维护刷新),再找不到时则查找/lib/usr/lib目录。
4.如何制作SO gcc生成so时使用-shared参数。
有了如上这些基础后,我们还是实例学习下如何使用so这玩意:
slam.c(编译成slam.so):
#include <stdio.h>

void print(char *str)
{
        printf("%s\n", str);
}
cso_exam.c
#include <stdio.h>
#include <dlfcn.h>

int main(int argc, char * argv[])
{
        if (argc != 2) {
                printf("Usage:%s whattoprint\n", argv[0]);
                return 0;
        }

        void * slam_handle;
        void (*print_func)(char * str);

        slam_handle = dlopen("slam.so", RTLD_LAZY);
        if (!slam_handle) {
                printf("dlopen failed.\n");
                return -1;
        }

        print_func = (void (*)(char*))dlsym(slam_handle, "print");
        if (dlerror() != NULL) {
                printf("dlsym failed.\n");
                return -1;
        }

        (*print_func)(argv[1]);

        return 0;
}
Makefile
all:
        gcc -o slam.so -shared -fPIC slam.c
        gcc -rdynamic -o cso cso_exam.c -ldl

clean:
        rm -rf slam.so cso
对应的源码文件目录树如下:
/home/xinu/xinu/c_cpp/c_so_example/
 
├── cso_exam.c
 
├── Makefile
 
└── slam.c 至此,所有准备工作都搞定了,接下来make后会在当前目录下生成csoslam.so两文件,为了让程序运行时搜索库能是当前目录,我们执行如下命令:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
接下来运行./cso hello就不会提示找不到库了。
参考网址:
http://blog.csdn.net/gubenpeiyuan/article/details/16864771http://www.eifr.com/article.php?id=1766&page=1
http://hi.baidu.com/mcu99/item/56784b36c3465485b611db75

评论

此博客中的热门博文

I/O映射之I/O端口

通过Netlink检测网线插拔

使用seq_file