so文件在Linux中为共享库,与Windows下的dll类似。
so文件可供多个进程调用,但通过共享库并不能实现不同进程间的通讯,因为同一个so被不同进程加载到不同的内存空间。
一、so文件的编译方法
so文件不需要有main函数,它需要进程调用它。
编译时,gcc需要加 –fPIC 选项,可使gcc产生与位置无关的代码。
链接时,gcc使用 –shared 选项,指示生成一个共享库文件。
共享库的文件名以lib开头,扩展名为 .so。
编写so文件的例子:
test.c文件中直接写函数,不要头文件和main函数。
makefile文件如下:
.SUFFIXES: .c .o
CC=gcc
SRCS=test.c
OBJS=$(SRCS:.c=.o)
EXE=libtest.so
all: $(OBJS)
$(CC) -o $(EXE) $(OBJS) -shared
@echo '^_^^_^^_^^_^^_^^_^OK^_^^_^^_^^_^^_^^_^'
.c.o:
$(CC) -Wall -g -fPIC -o $@ -c $<
clean:
-rm -f $(OBJS)
-rm-f core*
接下来编写so文件的头文件,如下:
#ifndef TEST_H_
#define TEST_H_
int max(int a,int b);
int add(int a,int b);
#endif /* TEST_H_ */
二、so文件的使用方法
为了让Linux能找到so文件的位置,需要在.bash_profile中添加export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:. 【改完后用 ..bash_profile命令使其生效】
或者将so文件放在Linux的系统目录/usr/lib/
调用so文件的例子:
a.c文件
#include <stdio.h>
#include "test.h"
int main(int arg, char *args[])
{
printf("max =%d\n", max(4,5));
printf("add =%d\n", add(4,5));
return 0;
}
makefile文件:
.SUFFIXES: .c .o
CC=gcc
SRCS=a.c
OBJS=$(SRCS:.c=.o)
EXE=a
all: $(OBJS)
$(CC) -L. -ltest -o $(EXE) $(OBJS)
@echo '^_^^_^^_^^_^^_^^_^OK^_^^_^^_^^_^^_^^_^'
.c.o:
$(CC) -Wall -g -o $@ -c $<
clean:
-rm -f $(OBJS)
-rm-f core*
其中,gcc -L. -ltest -o a a.o
-L.表示在当前路径下寻找so文件
-ltest意思为要链接libtest.so这个库文件
-o a 意思为编译后的可执行文件名为a
问题:当在cpp文件中包含test.h文件时,用g++链接libtest.so这个库时会报错。
解决方法:为了使编写的so文件同时可以被C或者C++文件调用,则需要修改一下h文件中的函数申明部分。增加带有_cplusplus的预编译指令。_cplusplus是c++编译器预定义的一个宏。若使文件用C++和C编译器都能调用,则头文件写法如下所示:
#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_ */