美文网首页
Linux下C编程使用动态链接库

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

作者: 网路元素 | 来源:发表于2019-10-28 08:13 被阅读0次

    为了方便程序功能的后期升级扩展,在程序设计时经常会用到动态库,这样子程序只有到运行阶段才会去加载动态库并且使用库中的函数,那么我们往往只需要更新DLL(Windows系统)或SO(Linux系统)文件即可达到,同时打包成库也有利于保密和核心技术的积累,话不多说,接下来看看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_RPATH和DT_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后会在当前目录下生成cso和slam.so两文件,为了让程序运行时搜索库能是当前目录,我们执行如下命令: 

    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:. 

    接下来运行./cso hello就不会提示找不到库了。 

    参考网址: 

    http://blog.csdn.net/gubenpeiyuan/article/details/16864771
    http://www.eifr.com/article.php?id=1766&page=1 
    http://hi.baidu.com/mcu99/item/56784b36c3465485b611db75

    相关文章

      网友评论

          本文标题:Linux下C编程使用动态链接库

          本文链接:https://www.haomeiwen.com/subject/opfryctx.html