so共享库

来源:互联网 发布:网络音响 编辑:程序博客网 时间:2024/06/16 06:26

共享库so

  • so文件在Linux中是共享库,与windows中的dll类似。
  • so文件中的函数可供多个进程调用,最大实现二进制代码的复用。
  • 共享库为维护提供方便,当修正一些错误的时候用户只需要获得升级后的so并且安装即可。

注意:
同一个so会被不同进程加载到不同的内存段。

so文件编译

  • so文件的源文件不需要main()函数,即使有也不会被执行
  • 编译的时候gcc需要加一些-fPIC选项,加这个目的是so里面的代码与位置无关,只需要编译成二进制可执行就行
  • 连接的时候gcc使用-shared选项,指示生成一个共享库文件。
  • 共享库文件名称要以lib开头,拓展名为.so

例子说明

比如我们现在来写一个so文件实现简单的功能

文件名称叫做test.c

int max(int a,int b){    return a+b;}int add(int a,int b){    return a+b;}

编写makefile文件

$(CC) -Wall -g -fPIC -o $@ -c $<其中fPIC表示代码生成和位置无关

.SUFFIXES: .c .oCC=gccSRCS=test.cOBJS=$(SRCS:.c=.o)EXE=libtest.soall: $(OBJS)    $(CC) -o $(EXE) $(OBJS)    @echo '^_^ ^_^ ^_^ ^_^ ^_^ ^_^ OK ^_^ ^_^ ^_^ ^_^ ^_^ ^_^'.c.o:     $(CC) -Wall -g -fPIC -o $@ -c $<clean:    -rm -f $(OBJS)    -rm -f core*

然后执行在代码所在目录执行make就会生成libtest.so文件

对于so文件需要编写头文件,来说明so里面有什么函数,函数参数和返回值是什么。
所以我们现在来按照上面的编写头文件test.h

#ifndef TEST_H_#define TEST_H_int max(int a,int b);int add(int a,int b);#endif

为了能让Linux找到so文件的位置,需要:

  1. .bash_profile中添加export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.

    • 或者将so放入usr/lib目录
    • 在c文件中使用so文件,首先需要#include相关h文件
    • gcc连接时候需要 -L参数指定so文件的存放路径,-l参数指定so文件名称
    以libtest.so为例子gcc -L -ltest -o a.o其中-L表示在当前目录下寻找so文件-ltest意思为要连接libtest.so这个库文件-o a意思是为编译后的可执行文件名为a

上面我们已经可以成功编写一个so动态库并添加到我们的当前目录中去.下面我们将使用这个so动态库

text.h

#ifndef TEST_H_#define TEST_H_#ifdef __cplusplusextern "C"{#endifint max(int a, int b);int add(int a, int b);#ifdef __cplusplus}#endif#endif

其中头文件中的extern "C"声明所包含的代码是用C的方式写的,其中extern "C"是C++的关键字,是告诉C++编译器,所包含代码是用C写的。

其中#ifdef __cplusplus是为了兼容C/C++混合开发准备的,只有是C++编译器的时候才识别这个宏定义。


makefile文件

是在连接的时候加$(CC) -L. -ltest -o $(EXE) $(OBJS)参数-L,-ltest
意思是在当前目录下找到test这个库编译。

.SUFFIXES: .c .oCC=gccSRCS=a.c    OBJS=$(SRCS:.c=.o)EXE=aall: $(OBJS)    $(CC) -L. -ltest -o $(EXE) $(OBJS)     @echo '^_^ ^_^ ^_^ ^_^ ^_^ ^_^ OK ^_^ ^_^ ^_^ ^_^ ^_^ ^_^'.c.o:     $(CC) -Wall -g -o $@ -c $<clean:    -rm -f $(OBJS)    -rm -f core*
0 0
原创粉丝点击