共享库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\n", max(4, 5));
        printf("%d\n", 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_ */

 

posted @ 2015-05-12 00:34  张仕传  阅读(584)  评论(0编辑  收藏  举报