zoukankan      html  css  js  c++  java
  • 共享库so

    so文件在linux中为共享库,与windows下的dll类似。
    so文件中的函数可供多个进程调用,最大可能的提供二进制代码的复用。
    共享库可以使代码的维护工作大大简化,当修正了一些错误或者添加了新特性的时候,用户只需要获得升级后的so并安装他就可以。
    注:即使不同的进程调用同一个so文件,通过共享库并不能实现不同进程间的通讯,因为同一个so被不同进程加载加载到不同的内存空间。
     
     
    so文件编译方法
      –so文件的源文件中不需要有main函数,即使有也不会被执行。
      –编译的时候gcc需要加-fPIC选项,这可以使gcc产生与位置无关的代码。
      –连接的时候gcc使用-shared选项,指示生成一个共享库文件。
      –共享库文件名要以lib开头,扩展名为.so。
     
    编写so的例子。
    int max(int a, int b)
    {
        if (a > b)
            return a;
        else
            return b;
    }
    
    int add(int a, int b)
    {
        return a + b;
    }
    #ifndef TEST_H_
    #define TEST_H_
    
    int max(int a, int b);
    int add(int a, int b);
    
    
    #endif /* TEST_H_ */
    .SUFFIXES:.c .o
    
    CC=gcc
    SRCS=test.c
    
    EXEC=libtest.so
    
    OBJS=$(SRCS:.c=.o)
    
    start:$(OBJS)
        $(CC) -shared -o $(EXEC) $(OBJS) 
    
    .c.o:
        $(CC) -g -fPIC -o $@ -c $<
    
    clean:
        rm -f $(OBJS)
    so文件使用方法
      –为了让linux能找到so文件的位置,需要在.bash_profile中添加export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
      –或者将so文件放入linux的系统目录/usr/lib/
      –在c文件中使用so文件,首先需要 #inluce相关h文件。
      –gcc连接时添加 –L参数指明so文件存放路径,-l参数指明so文件名
      –以libtest.so文件在当前路径下举例

    gcc -L. -ltest -o a a.o

    其中-L.意思为在当前路径下寻找so文件

      -ltest意思为要链接libtest.so这个库文件

      -o a 意思为编译后的可执行文件名为a

    u调用so的例子
    #include "test.h"
    #include <stdio.h>
    
    int main()
    {
            printf("%d
    ", max(4, 5));
            printf("%d
    ", add(4, 5));
            return 0;
    }
    .SUFFIXES:.c .o
    CC=gcc
    SRCS=a.c
    EXEC=a
    OBJS=$(SRCS:.c=.o)
    start:$(OBJS)
            $(CC) -L. -ltest -o $(EXEC) $(OBJS) 
    .c.o:
            $(CC) -o $@ -c $<
    clean:
            rm -f $(OBJS)
    当我们在cpp文件中包含test.h文件,用g++链接libtest.so这个库时会报错:

      (.text+0x19): undefined reference to `max(int, int)'

      (.text+0x3d): undefined reference to `add(int, int)'

    为了使我们编写的so文件同时可以被C或者C++调用,我们需要修改一下h文件中的函数申明部分。
    增加带有__cplusplus的预编译指令。
    __cplusplus是c++编译器预定义的一个宏,比如用g++的时候这个宏就被提前定义了
     
     
    编写so的例子
      –test.h头文件
    如果是c++编译器会默认定义__cplusplus这个宏。
    当使用gcc编译的时候产生如下结果:

    int max(int a, int b);

    int add(int a, int b);

    当使用g++编译的时候,产生如下结果:

    extern "C"{

    int max(int a, int b);

    int add(int a, int b);

    }

    #ifndef TEST_H_
    #define TEST_H_
    
    #ifdef __cplusplus
    extern "C"{
    #endif
    
    int max(int a, int b);
    int add(int a, int b);
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif /* TEST_H_ */
  • 相关阅读:
    经典卷积神经网络(LeNet、AlexNet、VGG、GoogleNet、ResNet)的实现(MXNet版本)
    Gluon 实现 dropout 丢弃法
    『MXNet』第六弹_Gluon性能提升 静态图 动态图 符号式编程 命令式编程
    Gluon炼丹(Kaggle 120种狗分类,迁移学习加双模型融合)
    固定权重 关于Mxnet的一些基础知识理解(1)
    『MXNet』第四弹_Gluon自定义层
    积神经网络(CNN)的参数优化方法
    推荐!PlayGround:可视化神经网络
    激活函数可视化
    Tuxedo低版本客户端(Tuxedo 9)连接到高版本Tuxedo服务端(Tuxedo 12.1.3)的问题
  • 原文地址:https://www.cnblogs.com/shichuan/p/4496170.html
Copyright © 2011-2022 走看看