精华内容
下载资源
问答
  • 本文主要通过导出一个log文件操作的类,来说明linuxso库的生成与调用。先说明一下本文中的几个文件和其作用: 1)ilogfile.h主要用于定义Clogfile类的借口和声明一个C风格的create导出函数,该文件为导出文件,在用...

    本文主要通过导出一个log文件操作的类,来说明linux下so库的生成与调用。先说明一下本文中的几个文件和其作用:
    1)ilogfile.h
     主要用于定义Clogfile类的借口和声明一个C风格的create导出函数,该文件为导出文件,在用g++编译的时候需放在最前面。
    2)logfile.h 主要定义了Clogfile类的头文件。
    3)logfile.cpp 主要提供了Clogfile类的定义。
    4)create.cpp 主要定义了一个create函数,在使用时用户可以通过该函数获取一个Clogfile类的对象地址,并将该地址转换为接口对应的Ilogfile类型,这样就对最终用户封闭了Clogfile类。
    根据上述1)、2)、3)、4)文件生成一个log.so的动态链接库。
    5) main.cpp 该文件定义了一个main函数,在该函数中通过调用生成的
    动态链接库log.so来实现对Clogfil类的操作。
    具体文件的内容如下:
    -----------------
    ilogfile.h文件---------------------------
     

    //ilogfile.h
    #ifndef _ILOGFILE_H
    #define _ILOGFILE_H
    
    #include<string>
    using namespace std;
    class Ilogfile
    {
    public:
        virtual    bool open() = 0;
        virtual void close() = 0;
        virtual void write(const string& logItemId, const string& logItemContent) = 0;
        virtual string read(const string& logItemId) = 0;
    };
    extern "C" Ilogfile*create();
    
    #endif//_ILOGFILE_H


    -----------------logfile.h文件---------------------------
     

    //logfile.h
    #include"ilogfile.h"
    #include<iostream>
    using namespace std;
    
    class Clogfile : public Ilogfile
    {
    public:
        bool open();
        void close();
        void write(const string& logItemId, const string& logItemContent);
        string read(const string& logItemId);
    
    };


    ----------------logfile.cpp文件----------------------------
     

    //logfile.cpp
    #include "logfile.h"
    bool Clogfile::open()
    {
        cout<<"This is function : Clogfile::open()"<<endl;
        return true;
    }
    
    void Clogfile::close()
    {
        cout<<"This is function : Clogfile::close()"<<endl;
    }
    
    void Clogfile::write(const string& logItemId, const string& logItemContent)
    {
        cout<<"This is function : Clogfile::write(...)"<<endl;
    }
    
    string Clogfile::read(const string& logItemId)
    {
        cout<<"This is function : Clogfile::read(...)"<<endl;
    }


    ----------------create.cpp文件----------------------------
     

    //create.cpp
    
    #include"logfile.h"
    Ilogfile* create()
    {
        return (Ilogfile*)new Clogfile();
    }


    ---------------main.cpp文件-----------------------------
     

    //main.cpp
    #include <stdlib.h>
    #include<stdio.h>
    #include<dlfcn.h>
    #include"ilogfile.h"
    #include<iostream>
    using namespace std;
    typedef Ilogfile* (*PFunc)();
    int main()
    {
        void *SoLib = NULL ;
        SoLib=dlopen("./log.so",RTLD_LAZY);
        const char *err = dlerror();
        if(err != NULL)
        {
            fputs(err, stderr);
            exit(1);
        }
        PFunc pcreate = NULL;
        pcreate = (PFunc)dlsym(SoLib,"create");
        if(NULL == pcreate)
        {
            cout<<"Can not get create function from log.so"<<endl;
            return 0;
        }
        Ilogfile* plogfile = (*pcreate)();
        plogfile->open();
        return 0;
    }


    接下来通过快捷键“alt+Ctrl+t”打开终端命令框,并进入到上述几个文件保存的目录中,然后生成动态库并进行调用,过程如下:
    1)生成动态库log.so,命令为:g++ ilogfile.h logfile.h logfile.cpp create.cpp -fPIC -shared -o log.so
    注意:上述命令里ilogfile.h为导出文件,要放在第一个位置。
    2)编译main.cpp生成调用动态库的main文件,命令为:g++ main.cpp -o main -ldl
    3) 执行生成的main文件,命令为:./main
    需要注意,在第2)步中需要加上指令-ldl,l是L的小写形式,如果不加上,则会出现下面的错误:
    main.cpp:(.text+0x21): undefined reference to `dlopen'
    main.cpp:(.text+0x2a): undefined reference to `dlerror'
    main.cpp:(.text+0x72): undefined reference to `dlsym'

    展开全文
  • linux .so 生成与调用

    2015-01-28 21:21:00
    方法一: 有test.h,test1.c,test2.c,main.c,其中: 1 // main.c 2 #include "test.h" 3 4 void main(){ 5 test1(); 6 test2();...生成.so: gcc test1.c test2.c -fPIC -shared -o libtest.so
    方法一:
    有test.h,test1.c,test2.c,main.c,其中:
    1 // main.c
    2 #include "test.h"
    3 
    4 void main(){
    5     test1();
    6     test2();              
    7 }

    生成.so: gcc test1.c test2.c -fPIC -shared -o libtest.so
    调用.so: gcc main.c -L. -ltest -o main
         export LD_LIBRARY_PATH=/home/linden/projects  //LD_LIBRARY_PATH的意思是告诉loader在哪些目录中可以找到共享库. 可以设置多个搜索目录, 这些目录之间用冒号分隔开
         ./main即可

    方法二:
    1 //test.h
    2 
    3 #include "stdio.h"
    4 void test1();
    5 void test2();

     

    1 //test1.c
    2 
    3 #include "stdio.h"
    4 void test1(){
    5         printf("this is test11111111...\n");
    6 }
    1 //test2.c
    2 
    3 #include "stdio.h"
    4 void test2(){
    5         printf("this is test22222222...\n");
    6 }
     1 //main.c
     2 
     3 #include "stdio.h"
     4 #include "stdlib.h"
     5 #include "dlfcn.h"
     6 #include "test.h"
     7 
     8 void main(){
     9         void *SoLib;
    10         int (*So)();
    11         SoLib = dlopen("./libtest.so",RTLD_LAZY);  ////加载libtest.so  
    12         So = dlsym(SoLib,"test1");  //声名test1方法  
    13         (*So)("");  //执行test1方法
    14         return;
    15 }

    生成.so文件:gcc test.h test1.c test2.c -fPIC -shared -o libtest.so

    调用.so文件:gcc main.c -o test -ldl

    展开全文
  • $gcc -c hello.c -o hello.o1....连接成动态库生成动态库用gcc来完成,由于可能存在多个版本,因此通常指定版本号:$gcc -shared -Wl,-soname,libhello.so.1 -o libhello.so.1.0 hello.o另外再建立...

    $gcc -c hello.c -o hello.o

    1.连接成静态库

    连接成静态库使用ar命令,其实ar是archive的意思

    $ar cqs libhello.a hello.o

    2.连接成动态库

    生成动态库用gcc来完成,由于可能存在多个版本,因此通常指定版本号:

    $gcc -shared -Wl,-soname,libhello.so.1 -o libhello.so.1.0 hello.o

    另外再建立两个符号连接:

    $ln -s libhello.so.1.0 libhello.so.1

    $ln -s libhello.so.1 libhello.so

    这样一个libhello的动态连接库就生成了。最重要的是传gcc -shared 参数使其生成是动态库而不是普通执行程序.

    -Wl 表示后面的参数也就是-soname,libhello.so.1直接传给连接器ld进行处理。实际上,每一个库都有一个soname,当连接器发现它正 在查找的程序库中有这样一个名称,连接器便会将soname嵌入连结中的二进制文件内,而不是它正在运行的实际文件名,在程序执行期间,程序会查找拥有 soname名字的文件,而不是库的文件名,换句话说,soname是库的区分标志。

    这样做的目的主要是允许系统中多个版本的库文件共存,习惯上在命名库文件的时候通常与soname相同

    libxxxx.so.major.minor

    其中,xxxx是库的名字,major是主版本号,minor 是次版本号

    至于头文件的使用 只要.c文件和.h文件在同一目录下就可以直接用#include "your.h" 如果在.c文件的上层目录 那只要做如下修改#include "../your.h" 就能够让你的编译器找到了!

    一、创建共享库

    1 单独编译SList.cpp,编译时需要传入-fPIC选项,告诉编译器生成位置无关代码.

    位置无关代码可以被加载到地址空间的任意位置而不需要修改.

    [root@LEE src]# ls

    main.cpp SList.cpp SList.h

    [root@LEE src]# g++ -fPIC -g -c SList.cpp

    2 当链接到库时,为链接器传入-shared选项,把目标文件SList.o链接为共享对象

    libSList.so.1.0.1

    每个共享库都有一个特定的搜索名(soname).搜索名约定如下:

    lib+库名+.so+.版本号

    在文件系统中,搜索名是一个指向实名的符号连接.每个共享库也有一个特定的实名,约定如下:

    搜索名+.子版本号+.发布号

    你可以使用一个特殊的编译器选项-Wl,option,将option传给ld,用逗号分隔多个option,

    为了在所有的系统上得到最好结果,链接libSList到标准C++库上

    [root@LEE src]# g++ -g -shared -Wl,-soname,libSList.so.1 -o libSList.so.1.0.1 SList.o -lstdc++

    [root@LEE src]# ls

    libSList.so.1.0.1 main.cpp SList.cpp SList.h SList.o

    libSList.so.1是搜索名,libSList.so.1.0.1是实名,SList.o是目标文件(也可以是多个目标文件的列表)

    ,-lstdc++是库需要访问的库(也可以是库的列表-llibrary,关于此选项参考附录.)

    3 创建一个从soname链接到库

    [root@LEE src]# ln -fs libSList.so.1.0.1 libSList.so.1

    [root@LEE src]# ln -fs libSList.so.1 libSList.so

    4 使用-L使链接器在当前目录中查找库,并且使用-lSList告诉它要链接哪个库

    [root@LEE src]# g++ -g -c main.cpp -o main.o

    [root@LEE src]# g++ -g -o main main.o -L. -lSList

    [root@LEE src]# ls

    libSList.so    libSList.so.1.0.1 main.cpp SList.cpp SList.o

    libSList.so.1 main               main.o    SList.h

    5 运行命令

    [root@LEE src]# LD_LIBRARY_PATH=$(pwd) ./main  [In the same line]

    4->17->19->10->23->21->11->20

    LD_LIBRARY_PATH

    提供用来搜索库的目录路径,以冒号作为间隔.正常情况下它不应该被设置,因为系统文件

    /ect/ld.so.conf提供了默认的路径.

    二、使用链接库

    当运行一个程序时,动态装载器通常在/ect/ld.so.conf.d目录查找程序所需要的库.但是,如果

    LD_LIBRARY_PATH 环境变量被设置,它首先扫描在LD_LIBRARY_PATH 中列出的目录.对于上一节5,如果直接运行

    命令 ./main,会出现找不到库的现象.如:

    [root@LEE src]# ./main

    ./main: error while loading shared libraries: libSList.so.1: cannot open shared object file: No such file or directory

    上述问题的解决方案有两种(我能想到的):

    1 如果LD_LIBRARY_PATH 没设定:

    拷贝libSList.so到目录 /usr/local/lib (同理也可以拷到/usr/lib下)

    [root@LEE src]# cp libSList.so /usr/local/lib

    [root@LEE src]# ldconfig /usr/local/lib

    [root@LEE src]# ./main

    4->17->19->10->23->21->11->20

    2 如果LD_LIBRARY_PATH 设定:

    编辑.bash_profile文件

    添加LD_LIBRARY_PATH:=$LD_LIBRARY_PATH:/path/to/libSList.so(不包括 libSList.so)

    执行.bash_profile 文件.

    [root@LEE src]# . /root/.bash_profile

    [root@LEE src]# ./main

    4->17->19->10->23->21->11->20

    展开全文
  • Linux生成.so文件

    千次阅读 2016-07-28 09:47:00
    linux下的.so文件即Shared Libraries。Shared Library 是程序运行时加载的库文件。当一个shared library 被成功的安装以后,之后启动的所有程序都会自动使用最新的shared library。也就是说,生成一个.so文件并告诉...

    .so文件是什么?

    linux下的.so文件即Shared Libraries。Shared Library 是程序运行时加载的库文件。当一个shared library 被成功的安装以后,之后启动的所有程序都会自动使用最新的shared library。也就是说,生成一个.so文件并告诉编译器它的位置之后,所有的需要引入它的程序都可以同时调用它。

    使用.so文件有以下这么几个好处:

    • 升级库但是可以继续支持一些程序,这些程序想要使用较老版本的,或者不向后兼容的库。
    • 重写特定的库文件或者甚至可以在执行特定程序时,指定一个库文件的特定函数
    • 做以上这些的时候程序甚至可以正在使用着当前的库文件

    每一个shared library都有一个soname、一个real name、一个linker name。

    soname有一个前缀lib、自定义的短语、后跟一个.so、还有一个版本号。如:/usr/lib/libreadline.so.3

    real name是一个soname的实体,在文件名中包涵了真实的库版本号。real name相比soname添加了一个句点,一个次要版本号,另一个句点,和一个发型版本号。最后一个句点和发行版本号是可选的。次要号码和发行号码支持配置控制,使别人可以明白安装的是哪个确切的版本。

    linker name是没有任何版本号的soname。如/usr/lib/libreadline.so。

    管理shared libraries的关键就是将这个文件名拆开。当程序内部列出它们需要的shared libraries时,仅仅需要列出soname即可。相反的,当创建一个shared library时,你只需要创建一个特定的文件名(包括详细的版本信息)即可。当你安装了一个新版本的库时,你只需将它安装在一小部分特殊的文件夹中的一个之中,然后运行程序ldconfig。lgconfig将会检查现存的文件,并且创建real name的soname和symbolic link,同时设置好春村文件。缓存文件位于/etc/ld.so.cache。

    ldconfig并不设置linker name;通常这是在库安装时干的事,然后linker name作为指向最新soname或者realname的symbolic link被创建。

    symbolic link(软连接)是自己指定的。名字如: /usr/lib/libreadline.so.3.0。

    linker name就是一个与/usr/lib/libreadline.so.3相关联的symbolic link。

    如果以上看不懂的话,是的我也没看懂,只是大体翻译了这篇文章

    LD_LIBRARY_PATH
    这个路径中的库文件将被在正常寻找前首先寻找。

    注意事项

    1. .so文件(也就是Shared Libraries)必须以lib开头,以.so结尾,比如:libalpha.so。(作为特例,一些最低级的C库并不是以lib开头的)
    2. 必须将自定义的文件加入到LD_LIBRARY_PATH中才能运行。

    生成并测试.so文件。

    aplusb.c

    #include <iostream>
    #include "aplusb.h"
    using namespace std;
    int aPlusB(int a, int b)
    {
        int c = a + b;
        return c;
    } 

    aplusb.h

    #ifndef APLUSB_H__
    #define APLUSB_H__
    extern int aPlusB(int a, int b);
    #endif

    main.c

    #include <iostream>
    #include "aplusb.h"
    using namespace std;
    int main(void)
    {
        int a = 1;
        int b = 2;
        int c = 0;
        c = aPlusB(a, b);
        cout<<c<<endl;
        return 0;
    }

    第一步:创建PIC文件

    g++ -c -fPIC aplusb.c

    pic代码是位置无关代码,程序运行时计算机会找文件中指定的内存地址去读取数据,但是当读取一个库文件时,库本身指定的地址必须是与内存地址无关的。此时生成了aplusb.o。注意-fPIC比-fpic兼容性要高。

    -c 为编译和汇编但是不链接。

    生成的.o文件为机器码。

    第二步:用第一步生成的文件去创建.so文件。

    g++ -shared -o libaplusb.so aplusb.o

    第三步:链接

    g++ -L/home/lee/JNI -o main main.c -laplusb

    第四步: 保证运行时可以调用

    $ export LD_LIBRARY_PATH=/home/lee/JNI:$LD_LIBRARY_PATH

    至此

    第五部:运行

    lee@lee-computer:~/JNI$ ./main
    3

    结果为3。调用成功。

    展开全文
  • $gcc -c hello.c -o hello.o1....连接成动态库生成动态库用gcc来完成,由于可能存在多个版本,因此通常指定版本号:$gcc -shared -Wl,-soname,libhello.so.1 -o libhello.so.1.0 hello.o另外再建立...
  • linux so生成(一)

    2015-01-16 12:09:16
    $gcc -shared -Wl,-soname,libhello.so.1 -o libhello.so.1.0 hello.o 另外再建立两个符号连接: $ln -s libhello.so.1.0 libhello.so.1 $ln -s libhello.so.1 libhello.so 这样一个libhello的动态连接
  • C++Linux生成SO

    2021-03-03 17:40:12
    1.制作so文件:libadd_c.so add.c: int add(int a, int b) { return a + b; } 编译: gcc -shared -fpic -lm -ldl -o libadd_c.so add.c 2.编写测试函数 test.cpp #include <stdio.h> #include <...
  • linux生成so库及调用

    2017-07-12 11:35:29
    tof.h #include "stdio.h" void tof(); tof.cpp #include "tof.h" #include using namespace std; void tof() ...生成so 库  gcc tof.cpp -fPIC -shared -o libtof.so -fPIC
  • $gcc -c hello.c -o hello.o1....连接成动态库生成动态库用gcc来完成,由于可能存在多个版本,因此通常指定版本号:$gcc -shared -Wl,-soname,libhello.so.1 -o libhello.so.1.0 hello.o另外再建立...
  • 这是个LINUX生成SO文件,和调用SO库的程序示例.
  • linux生成.so文件和.a文件

    千次阅读 2019-01-23 10:48:37
    原文链接:...   linux生成.so文件和.a文件 test.h 1 #ifndef _TEST_H_ 2 #define _TEST_H_ 3 4 void TestA(); 5 void TestB(); 6 7 #endif   t...
  • linux生成动态链接库so文件

    千次阅读 2015-09-29 16:30:11
    怎样在linux生成动态链接库即.so文件? 一、 首先需要一个好的编译工具,直接用gcc命令行编译已经不再是一个明智之举了,一个好的带编译工具的环境是很重要的,我选择的是easyeclipse,它集成了CDT,可以很...
  • linux生成ffmpeg的so包用于android开发浅尝 安装linux 下载ndk以及ffmpeg 修改配置文件 生产so包 首先,安装我是在windows里面安装的vwmware,然后安装的ubuntu虚拟机; 安装好以后,首先配置相关软件; //1....
  • 生成动态库 1.创建QT项目,创建C++Liberary 一路next,选取模块的时候按需要选择,默认仅选择QtCore模块 2.在自定义的类中写一个hello()的测试函数 XXX_global.h是所有Library项目都有的...一般会有XXX.so.1.0....
  • linux生成.so并运行程序加载该.so

    千次阅读 2016-10-26 14:33:01
    此时如果我们想要生成动态库,要做的工作其实非常简单,输入gcc -shared -fPIC -o libtest.so test.c即可。回车后输入ls,我们就可以发现当前目录下面出现了libtest.so文件 在上面的代码当中,我们发现使用到了...
  • linux环境生成.so文件

    2013-09-06 09:43:00
    libSList.so.1是搜索名,libSList.so.1.0.1是实名,SList.o是目标文件(也可以是多个目标文件的列表) ,-lstdc++是库需要访问的库(也可以是库的列表-llibrary,关于此选项参考附录.) 3 创建一个从soname链接到库 ...
  • public class TestHello { //继承Library,用于加载库文件 --Class mapping public interface CLibrary extends Library { // 加载libhello.so链接库 public String JNA_ImgProcess = "HelloToJava"; public C...
  • linux生成so文件: 准备.cpp文件和.h文件。cpp文件为源码,包含对导出函数的实现,最好使用c来写,方法上使用 extern "C" 修饰,绝对不可使用__stdcall来修饰,此修饰词为Windows文件的修饰词,生成dll时可以加...
  • 为了不暴露源码,将c文件生成so动态库来给别人调用 记录一下方法 首先简单的创建一些测试文件:test.h a.c b.c c.c 如下: test.h #include <stdio.h> void a(); void b(); void c(); a.c #include "test.h...
  • 将.c文件编译成.o,再重新转换成.so或者.dll文件 gcc -fPIC -D_REENTRANT -I /usr/lib/jvm/java/include -I /usr/lib/jvm/java/include/linux -c MyJni.c 生成文件:MyJni.o 6. 将.o文件编译成.so文件 gcc -shared ...
  • 动态库的引入及减少了主代码文件的大小,同时生成的动态库又是动态加载的,只有运行的时候才去加载,linux 下的 动态库 .so 就像windows下的 DLL一样。有关动态库的概念自行上网搜。一下是创建及引用动态库 ...
  • 问:我源文件为main.c, x.c, y.c, z.c,... 生成动代连接库,假设名称为libtest.so gcc x.c y.c z.c -fPIC -shared -o libtest.so #2. 将main.c和动态连接库进行连接生成可执行文件 gcc main.c -L. -ltest -o
  • 文章目录动态链接linux生成.so文件linux使用.so文件静态链接linux生成.a文件linux使用.so文件 动态链接 简单理解就是记录文件的路径,通过路径找到对应文件,文件删除,库则无法使用 优点:不占空间 缺点:效率低 ...
  • #elif defined(_WIN32) || defined(WIN32) || defined(WIN32) #ifdef _WIN32 #include #include #else #include #include #include #include #endif 实例 OUTPUTFILE=libPcie55.so all: Pcie55 Pcie55:pkg.o sm4.o ...

空空如也

空空如也

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

linuxso生成

linux 订阅