SO文件的编译的方法
-so文件中不需要有main函数,即使有也不会被执行
-编译的时候gcc需要加选项-FPIC,这可以使gcc产生与位置无关的代码。
-链接的时候gcc使用-shared选项,指示生成一个共享库文件。
-共享库文件的要以lib开头,扩展名为so
int max(int a, int b)
{
if(a > b)
return a;
else
return b;
}
int add(int a, int b)
{
return a + b;
}
makefile 文件的格式
.SUFFIXES:.c .o
CC=gcc
SRCS=test.c
OBJS=$(SRCS:.c=.o)
EXEC=libtest.so
start: $(OBJS)
$(CC) -shared -o $(EXEC) $(OBJS)
@echo "------------------ok---------------"
.c.o:
$(CC) -Wall -g -FPIC -o $@ -c $<
clean:
rm -rf $(EXEC) $(OBJS)
make一下就可以生成这个so文件了
如何去使用这个so文件呢?
Linux 会默认在/usr/lib/ 目录下找so文件
-为了让linux能找到so文件的位置,需要在.bash_profile中添加export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
或者将so文件放入linux的系统目录/usr/lib/ (修改.bash_profile 文件记住. .bash_profile 执行一下)
-在c文件中使用so文件,首先需要 #inluce相关h文件。
gcc连接时添加 –L参数指明so文件存放路径,-l参数指明so文件名
以libtest.so文件在当前路径下举例
gcc -L. -ltest -o a a.o
.SUFFIXES:.c .o
CC=gcc
SRCS=a.c
OBJS=$(SRCS:.c=.o)
EXEC=a
start: $(OBJS)
$(CC) -L. -ltest -o $(EXEC) $(OBJS)
@echo "------------------ok---------------"
.c.o:
$(CC) -Wall -g -o $@ -c $<
clean:
rm -rf $(EXEC) $(OBJS)
其中-L.意思为在当前路径下寻找so文件
-ltest意思为要链接libtest.so这个库文件
-o a 意思为编译后的可执行文件名为a
当我们在cpp文件中包含test.h文件,用g++链接libtest.so这个库时会报错:
/home/root123/myhome/a.cpp:9: undefined reference to `max(int, int)'
/home/root123/myhome/a.cpp:11: undefined reference to `add(int, int)'
collect2: ld returned 1 exit status
make: *** [start] Error 1
为了使我们编写的so文件同时可以被C或者C++调用,我们需要修改一下h文件中的函数申明部分。
增加带有__cplusplus的预编译指令。
__cplusplus是c++编译器预定义的一个宏,比如用g++的时候这个宏就被提前定义了
生成一个头文件test.h
#ifdef __cplusplus
extern "C"
{
#endif
int max(int a, int b);
int add(int a, int b);
#ifdef __cplusplus
}
#endif
#endif
cd到宿主目录下面 .bash_profile 修改成可以可以在当前目录下面执行的PATH =:.
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programs
sh_profile
PATH=$PATH:$HOME/bin:.