精华内容
下载资源
问答
  • 动态链接库是一种通用的软件组件技术,是多种操作系统中提供基本服务的方式。比如Win32内核就是3个DLL文件构成。这种技术在Linux操作系统下也有对应的实现,就是Linux标准对象Standard Ojbect,对应的文件扩展名为....

     

    动态链接库是一种通用的软件组件技术,是多种操作系统中提供基本服务的方式。比如Win32内核就是3个DLL文件构成。这种技术在Linux操作系统下也有对应的实现,就是Linux标准对象Standard Ojbect,对应的文件扩展名为.so。

    下面通过一个简单的例子开始介绍Linux标准对象。

    void show()

    {

      printf("Standard Object by gashero/n");

    }

    保存为myso.c文件,按照如下编译: $ gcc -fPIC -shared -o libmyso.so myso.c 。

    执行生成一个libmyso.so文件,按照Linux标准对象的命名惯例,应该在库名称之前加上"lib"前缀,尽管不是必须的。编译开关-fPIC代表函数符号可以重定向,-shared代表编译结果是一个标准对象。

    下面我们编写调用程序:

    int main()

    {

      printf("Invoke my so/n");

      show();

      return 0;

    }

    保存为invoke.c,按照如下gcc开关编译:$ gcc -o test invoke.c ./libmyso.so 。编译生成test可执行文件。如上编译条件的最后一条需要是所调用的标准对象文件名,注意必须含有路径。如果只是使用libmyso.so,则必须确保这个文件在可访问的PATH下面。本例所使用的文件名"./libmyso.so"是当前路径下的,使用了相对路径。

    如下测试结果:

    $ ./test

    Invoke my so

    Standard Object by gashero

    参考原文:http://www.cppblog.com/mydriverc/articles/33164.html

    展开全文
  • 一、Linux生成动态链接库 //func.c # include <stdio.h> int add(int a , int b) { return a+b; } void func() { printf("hello world......\n"); } 命令行:gcc -shared -fpic -lm -ldl -o libfunc.so...

    一、Linux下生成动态链接库

    //func.c
    # include <stdio.h>
    
    int add(int a , int b)
    {
    	return a+b;
    }
    
    void func()
    {
        printf("hello world......\n");
    }
    

    命令行:gcc -shared -fpic -lm -ldl -o libfunc.so func.c
    可生成动态链接库.so文件

    二、Linux下调用动态链接库生成可执行文件

    //test.cpp
    # include <iostream>
    # include <cstdio>
    # include <dlfcn.h>
    # include <stdlib.h>
    
    using namespace std;
    
    int main()
    {
        int result = 0;
    
        void *handle = dlopen("./libfunc.so" , RTLD_LAZY);//相对地址和绝对地址都可以
    
        if(!handle)
        {
            cout<<"open lib error\n";
            cout<<dlerror()<<endl;
            return -1;
        }
    
        typedef int(*add_t)(int a, int b);//typedef函数指针
        add_t add = (add_t)dlsym(handle, "add");
        if(!add)
        {
            cout<<dlerror()<<endl;
            dlclose(handle);
            return -1;
        }
            
        int a, b;
        cout<<"请输入要相加的两个数:";
        cin>>a>>b;
        result = add(a, b);
    	cout<<a<<"+"<<b<<"="<<result<<endl;
    
        typedef void(*f_t)();
        f_t f = (f_t)dlsym(handle , "func");
        if(!f)
        {
            cout<<dlerror()<<endl;
            dlclose(handle);
            return -1;
        }
        f();
    
        dlclose(handle);
    
    	return 0;
    }
    

    命令行:g++ test.cpp -ldl -o test
    可实现test.c生成可执行文件test后,在运行的时候自动加载动态链接库里的函数

    三、调用动态链接库的函数说明

    函数原型: void *dlopen(const char *libname,int flag);
    功能描述: dlopen必须在dlerror,dlsym和dlclose之前调用,表示要将库装载到内存,准备使用。如果要装载的库依赖于其它库,必须首先装载依赖库。如果dlopen操作失败,返回NULL值;如果库已经被装载过,则dlopen会返回同样的句柄。
    参数中的libname一般是库的全路径,这样dlopen会直接装载该文件;也可以用相对地址。

    flag参数表示处理未定义函数的方式,可以使用RTLD_LAZY或RTLD_NOW。RTLD_LAZY表示暂时不去处理未定义函数,先把库装载到内存,等用到没定义的函数再说;RTLD_NOW表示马上检查是否存在未定义的函数,若存在,则dlopen以失败告终。

    函数原型: char *dlerror(void);
    功能描述: dlerror可以获得最近一次dlopen,dlsym或dlclose操作的错误信息,返回NULL表示无错误。dlerror在返回错误信息的同时,也会清除错误信息。

    函数原型: void *dlsym(void *handle,const char *symbol);
    功能描述: 在dlopen之后,库被装载到内存。dlsym可以获得指定函数(symbol)在内存中的位置(指针)。如果找不到指定函数,则dlsym会返回NULL值。但判断函数是否存在最好的方法是使用dlerror函数,

    函数原型: int dlclose(void *);
    功能描述: 将已经装载的库句柄减一,如果句柄减至零,则该库会被卸载。如果存在析构函数,则在dlclose之后,析构函数会被调用。

    四、注意:
    1、要生成动态链接库的文件必须是C语言写的,(C++会报错,但是一大佬解析完符号表就可以了)。而调用动态链接库的文件可以用C++。
    2、计算机系统基础课本上有 gcc -o myproc main.c ./mylib.so可以生成部分链接的可执行文件,在加载时,由加载器将控制权转到指定的加载器,然后进行重定位和加载共享库,之后动态链接器又把控制权转移到成语myproc。但一般还是使用上面的命令来调用动态链接库比较好。

    展开全文
  • 2. 编译动态链接库 3. 使用共享库 4. 执行程序 5. 参考资料 1. 编写C程序 比如编写myfunc.c文件,里面包含两个函数,一个是say_hello,另一个是cal_sum。 #include "myfunc.h" void say_hello() { printf(...

    目录

    1. 编写C程序

    • 比如编写myfunc.c文件,里面包含两个函数,一个是say_hello,另一个是cal_sum
    #include "myfunc.h"
    
    void say_hello()
    {
        printf("hello world\n");
    }
    
    
    int cal_sum(int x, int y)
    {
        return x + y;
    }
    
    • myfunc.c编写接口文件
    #ifndef __MY_FUNC_H
    #define __MY_FUNC_H
    
    #include <stdio.h>
    #include <stdlib.h>
    
    
    void say_hello();
    int cal_sum(int x, int y);
    
    #endif
    

    2. 编译动态链接库

    • 首先编译myfunc.c
    gcc -c -fPIC -o myfunc.o myfunc.c

    -c 表示只编译(compile),而不链接,输出目标文(obj文件)。
    -o 表示输出文件的文件名。
    -fPIC PIC指Position Independent Code, 生成适合在共享库中使用的与位置无关的代码。编译成共享库要求此选项。适用于动态链接并避免对全局偏移表大小的任何限制。

    • 生成共享库文件libmyfunc.so
    gcc -shared myfunc.o -o libmyfunc.so

    -share 生成一个共享对象,然后可以与其他对象链接以形成可执行文件。

    两条命令合成一条就是:

    gcc -fPIC -shared myfunc.c -o libmyfunc.so

    3. 使用共享库

    接下来我们使用test.c来调用共享库。test.c内容如下:

    #include "myfunc.h"
    
    int main(int argc, char const *argv[])
    {
        int result = 0;
    
        say_hello();
        result = cal_sum(2, 3);
        printf("%d\n", result);
    
        return 0;
    }

    编译上述包含.h头文件的程序,GCC编译器需要知道头文件的位置

    • 对于#include <...>,GCC编译器会在默认include搜索路径中寻找。
    • 对于#include "...",GCC编译器会在当前路径搜索.h文件。你也可以使用-I选项提供额外的搜索路径,比如-I /home/test/

    除此之外,GCC编译器还需要知道我们用了哪个库文件,库文件在哪里

    • 使用-l选项说明库文件的名字。这里,我们使用的是libmyfunc.so库文件,所以选项是这样写的:-l myfunc
    • 使用-L选项说明库文件的路径。这里,我们的库文件是在当前路径,所以选项是这样写的:-L .(.表示当前路径)。

    所以,最终我们链接库文件生成的可执行文件命令是这样的:

    gcc -o test test.c -l myfunc -L .

    附加:
    可以使用下面的命令,来获知系统的include默认搜索路径:

    $ gcc -print-prog-name=cc1 -v

    获知库默认搜索路径:

    $ gcc -print-search-dirs

    4. 执行程序

    $ ./test

    执行程序后发现出现这样的情况:
    ./test: error while loading shared libraries: libmyfunc.so: cannot open shared object file: No such file or directory

    这是因为执行程序的时候,操作系统不知道libmyfunc.so的位置,系统无法找到libmyfunc.so库文件。尽管我们用GCC编译的时候,用-L选项提供了libmyfunc.so文件的位置,但是这个信息并没有被写入到可执行程序里面。下面用命令ldd命令测试(ldd命令是用于显示可执行文件所依赖的库):

    $ ldd test
    
        linux-vdso.so.1 =>  (0x00007ffccc9fe000)
        libmyfunc.so => not found
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f0d31a44000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f0d31e0e000)
    

    可以看出可执行文件test无法找到libmyfunc.so库文件。

    解决办法有几个:

    1. libmyfunc.so放到gcc默认搜索目录,比如/usr/lib/x86_64-linux-gnu或者/lib/x86_64-linux-gnu都可以,这样做简单粗暴。但要是这样做的话,需要root权限来完成,除此之外,我感觉污染了整个系统。

    2. /etc/ld.so.conf.d目录下新建一个.conf文件,比如mylib.conf,在里面添加第三方库(libmyfunc.so)目录路径

    3. 设置LD_LIBRARY_PATH环境变量,比如export LD_LIBRARY_PATH=.。设置这个环境变量之后,操作系统将在先在LD_LIBRARY_PATH下搜索库文件,再到默认路径中搜索文件。这样,可执行文件就可以在LD_LIBRARY_PATH中找到第三方库(libmyfunc.so)的位置。

    4. 编译的时候添加-Wl,-rpath选项,比如gcc -o test test.c -l myfunc -L . -Wl,-rpath=.-Wl选项告诉编译器将后面的参数传递给链接器

    最后运行可执行文件test的结果:

    $ gcc -o test test.c -l myfunc -L . -Wl,-rpath=.
    $ ./test
    hello world
    5

    5. 参考资料

    1. C编译: 动态连接库 (.so文件)
    2. Linux动态库生成与使用指南
    3. Linux 动态库剖析
    4. Linux动态链接
    5. 运行时动态库:not found 及介绍-linux的-Wl,-rpath命令

    转载于:https://www.cnblogs.com/tonwes/p/9292301.html

    展开全文
  • 动态库so在Linux下用c和c++编程时经常会碰到,下面简单介绍动态库的编译和链接 1、动态库so的编译 下面通过一个例子来介绍如何生成一个动态库。 这里有一个头文件:so_test.h 三个c文件:test_a.c、test_b.c、test...
    动态库so在Linux下用c和c++编程时经常会碰到,下面简单介绍动态库的编译和链接


    1、动态库so的编译

    下面通过一个例子来介绍如何生成一个动态库。

    这里有一个头文件:so_test.h三个c文件:test_a.c、test_b.c、test_c.c

    我们将这几个文件编译成一个动态库:libtest.so。


    <span style="font-family:Courier New;font-size:14px;"><span style="color:#ff0000;">//so_test.h:</span><span style="color:#494949;">
    #include "stdio.h"
    void test_a();
    void test_b();
    void test_c();</span></span>

    <span style="font-family:Courier New;font-size:14px;"><span style="color:#ff0000;">//test_a.c:</span>
    #include "so_test.h"
    void test_a()
    {
      printf("this is in test_a...\n");
    }</span>

    <span style="font-family:Courier New;font-size:14px;"><strong><span style="color:#ff0000;">//test_b.c:</span><span style="color:#494949;">
    #include "so_test.h"
    void test_b()
    {
      printf("this is in test_b...\n");
    }</span></strong></span>


    <span style="font-family:Courier New;font-size:14px;"><strong><span style="color:#ff0000;">//test_c.c:</span><span style="color:#494949;">
    #include "so_test.h"
    void test_c()
    {
      printf("this is in test_c...\n");
    }</span></strong></span>


    将这几个文件编译成一个动态库:libtest.so

    $ gcc test_a.c test_b.c test_c.c -fPIC -shared -o libtest.so

    2、动态库的链接

    在1.中,我们已经成功生成了一个自己的动态链接库libtest.so,下面我们通过一个程序来调用这个库里的函数。

    程序的源文件为:test.c。

    <span style="font-family:Courier New;font-size:14px;"><span style="word-wrap: normal; word-break: normal; line-height: 21px; background-color: rgb(236, 240, 252);"><span style="color:#ff0000;">//test.c:</span></span><br style="color: rgb(73, 73, 73); line-height: 21px; background-color: rgb(236, 240, 252);" /><span style="word-wrap: normal; word-break: normal; line-height: 21px; color: rgb(73, 73, 73); background-color: rgb(236, 240, 252);">#include "so_test.h"</span><br style="color: rgb(73, 73, 73); line-height: 21px; background-color: rgb(236, 240, 252);" /><span style="word-wrap: normal; word-break: normal; line-height: 21px; color: rgb(73, 73, 73); background-color: rgb(236, 240, 252);">int main()</span><br style="color: rgb(73, 73, 73); line-height: 21px; background-color: rgb(236, 240, 252);" /><span style="word-wrap: normal; word-break: normal; line-height: 21px; color: rgb(73, 73, 73); background-color: rgb(236, 240, 252);">{</span><br style="color: rgb(73, 73, 73); line-height: 21px; background-color: rgb(236, 240, 252);" /><span style="word-wrap: normal; word-break: normal; line-height: 21px; color: rgb(73, 73, 73); background-color: rgb(236, 240, 252);">   test_a();</span><br style="color: rgb(73, 73, 73); line-height: 21px; background-color: rgb(236, 240, 252);" /><span style="word-wrap: normal; word-break: normal; line-height: 21px; color: rgb(73, 73, 73); background-color: rgb(236, 240, 252);">   test_b();</span><br style="color: rgb(73, 73, 73); line-height: 21px; background-color: rgb(236, 240, 252);" /><span style="word-wrap: normal; word-break: normal; line-height: 21px; color: rgb(73, 73, 73); background-color: rgb(236, 240, 252);">   test_c();</span><br style="color: rgb(73, 73, 73); line-height: 21px; background-color: rgb(236, 240, 252);" /><span style="word-wrap: normal; word-break: normal; line-height: 21px; color: rgb(73, 73, 73); background-color: rgb(236, 240, 252);">   return 0;</span><br style="color: rgb(73, 73, 73); line-height: 21px; background-color: rgb(236, 240, 252);" /><span style="word-wrap: normal; word-break: normal; line-height: 21px; color: rgb(73, 73, 73); background-color: rgb(236, 240, 252);">}</span></span>
    
    
    将test.c与动态库libtest.so链接生成执行文件test:

    $ gcc test.c -L. -ltest -o test


    测试是否动态连接,如果列出libtest.so,那么应该是连接正常了(如果失败参照4)

    $ ldd test


    执行test,可以看到它是如何调用动态库中的函数的。

    $ ./test


    3、编译参数解析
    最主要的是GCC命令行的一个选项:
    -shared该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号),不用该标志外部程序无法连接。相当于一个可执行文件

    -fPIC表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。

    -L.表示要连接的库在当前目录中

    -ltest编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.so来确定库的名称


    4、注意

    调用动态库的时候有几个问题会经常碰到,有时,明明已经将库的头文件所在目录 通过 “-I” include进来了,库所在文件通过 “-L”参数引导,并指定了“-l”的库名,但通过ldd命令察看时,就是死活找不到你指定链接的so文件,这时你要作的就是通过修改 LD_LIBRARY_PATH或者/etc/ld.so.conf文件来指定加载动态链接库的路径。通常这样做就可以解决库无法链接的问题了。


    LD_LIBRARY_PATH:这个环境变量指示动态连接器可以装载动态库的路径。

    当然如果有root权限的话,可以修改/etc/ld.so.conf文件,然后调用 /sbin/ldconfig来达到同样的目的,不过如果没有root权限,那么只能采用输出LD_LIBRARY_PATH的方法了。


    在linux下可以用export命令来设置这个值,在linux终端下输入:

    export LD_LIBRARY_PATH=/opt/test/bin:$LD_LIBRARY_PATH:   (/opt/test/bin为你的so文件所在目录
    然后再输入:export 
    即会显示是否设置正确   
    export方式在重启后失效,所以也可以用 vim /etc/bashrc ,修改其中的LD_LIBRARY_PATH变量。   

    例如:LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/au1200_rm/build_tools/bin。



    展开全文
  • 然后在将生成动态库.so放在/lib下,执行下面的 编译main.cpp:  g++ main.cpp -L. -lmycls-o main 或者自己添加搜索路径用1.-Wl,-rpath,动态库路径 2.-Wl,rpath=动态库路径 g++ main.cpp -Wl,-rpath=./...
  • Linux动态链接库生成与使用 动态链接库介绍 动态链接库是一种不可以直接执行的二进制程序文件,它允许程序共享执行一段公用的代码和资源。 在 Linux 平台上动态链接库是以 .so 作为后缀名的。 相对于静态链接库...
  • linux生成动态链接库

    2019-09-25 05:37:00
    步骤1、创建动态链接库创建caculate.c caculate.h两个文件编译生成libcac.so文件:gcc -shared -fPIC caculate.c -o libcac.so 2、创建测试程序创建 main.pc文件编译生成可执行文件:gcc main.c -o main -L ./ -lcac...
  • 通常情况下,对函数链接是放在编译时期(compile time)完成的。所有相关的对象文件(object file)与牵涉到的函数(library)被链接合成一个可执行文件(executable file)。程序在运行时,与函数再无瓜葛...
  • [Linux初级]Linux动态库生成链接方法 [Linux初级]Linux动态库生成链接方法 - 哥德巴赫猜想的日志 - 网易博客[Linux初级]Linux动态库生成链接方法 2007-07-25 15:27:23|分类: 编程 .....
  • Linux生成动态链接库

    千次阅读 2018-04-18 17:32:53
    【摘要】动态链接库是在编译器编译之后生成 obj 文件之后,将几个链接文件和动态链接库中...而今天,我要分享给大家一个可以自己实现动态链接库生成的小技巧,别说,这种小技巧在面试中还是会被经常问到的哦。方法...
  • linux静态链接库 库 库是写好的现有的,成熟的,可以复用的代码。现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常 本质上来说库是一种可执行代码的二进制形式...
  • 参考... 首先是动态调用动态库 test_so1.h和test_so1.cpp生成test_so1.so动态库。 test_so2.h和test_so2.cpp生成test_so2.so动态库。 test_dll.cpp生成test_dll可执行程序,test_dl通
  • 动态链接库是一种通用的软件组件技术,是多种操作系统中提供基本服务的方式。比如Win32内核就是3个DLL文件构成。这种技术在Linux操作系统下也有对应的实现,就是Linux标准对象Standard Ojbect,对应的文件扩展名为....
  •  通常情况下,对函数链接是放在编译时期(compile time)完成的。所有相关的对象文件(object file)与牵涉到的函数(library)被链接合成一个可执行文件(executable file)。程序在运行时,与函数再无...
  •  在链接动态库生成可执行文件时,并不会把动态库的代码复制到执行文件中,而是在执行文件中记录对动态库的引用。  程序执行时,再去加载动态库文件。如果动态库已经加载,则不必重复加载,从而能节省内存空间。 ...
  • linux动态库生成链接

    千次阅读 2016-05-03 07:57:50
    linux下动态生成和链接(.so) 本质上来说是一种可执行代码的二进制形式,可以被操作系统载入内存执行。...程序运行时的动态链接,多个进程可以链接同一个共享。动态在程序编译时并不会
  • linux 动态链接库问题

    2018-05-31 23:10:38
    生成动态链接库时可以用多个.c文件生成一个动态链接库,主程序调用时,要分别include进头文件。
  • 一个epoll.c源文件,需要经过预处理器,编译器,汇编器和链接器的处理后输出可执行...预处理器执行头文件和宏定义的简单替换,而编译器和汇编器生成可重定位目标文件(包括共享目标文件),链接生成可执行目标文件。
  • Linux动态链接库

    2015-10-22 16:26:00
    【重要资料】...动态链接库生成: 代码上与写静态链接库没什么区别,主要是在编译时,以两个文件举例: /*mylib.h*/void Print(); /*mylib.c*/#include#include "mylib.h" void Print...
  • 1. 简介在python、java等...而本文主要介绍的是跨平台编译:针对windows系统中的C++程序在linux编译成动态链接库的过程。2. .so及.dll介绍2.1 .dllWindows下动态链接库以 .DLL事实上和 EXE 文件一样,同属 PE 格式...
  • Linux下动态库生成和使用 一.动态库的基本概念 1.动态链接库是程序运行时加载的库,当动态链接库正确安装后,所有的程序都可以使用动态库来运行程序。动态链接库是目标文件的集合,目标文件在动态链接库...
  • Linux下动态库生成和使用 一.动态库的基本概念 1.动态链接库是程序运行时加载的库,当动态链接库正确安装后,所有的程序都可以使用动态库来运行程序。动态链接库是目标文件的集合,目标文件在动态链接库中的...
  • 动态链接库是一种通用的软件组件技术,是多种操作系统中提供基本服务的方式。比如Win32内核就是几个DLL文件构成。这种技术在Linux操作系统下也有对应的实现,就是Linux标准对象Standard Ojbect,对应的文件扩展名为....
  • linux动态链接库

    2014-02-18 21:12:00
    动态库*.so在linux下用c和c++编程时经常会碰到,最近在网站找了几篇文章介绍动态库的编译和链接,总算搞懂了这个之前一直不太了解得东东,这里做个笔记,也为其它正为动态链接库而苦恼的兄弟们提供一点帮助。...
  • linux动态链接库入门

    2014-03-05 13:58:10
    2在linux动态链接库一般使用.so作为扩展名,生成动态链接库的方法 gcc -shared -Wall -fPIC add.o -o libadd.so 3生成main.o gcc -c main.c 4 指定动态链接库路径,生成可执行文件gcc -o main main.o -ladd -L ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,579
精华内容 631
关键字:

linux动态链接库生成

linux 订阅