乒乓世界杯_u20世界杯最新战况 - chhtzx.com

SO文件的编写,编译,使用方法

4836

(1)SO文件简介

linux下的.so文件为共享库,相当于windows下的dll文件。在系统目录/usr/lib/下,我们可以看到很多应用程序库文件(常用的动态链接库和软件包的配置文件)。

(2)SO文件编译方法

A. SO文件没有main

我们首先编写简单的两个函数,然后把它编译成so文件

int max(int a,int b){

if(a>b)

return a;

else

return b;

}

int add(int a,int b){

return a+b;

}

B. makefile文件编写

(1)编译时gcc后加-fPIC,这可以使gcc产生于位置无关的代码;

(2)连接时,使用-shared,指示生成一个共享库文件;

(3)共享库文件一lib开头+扩展名.so;

makefile文件如下:

.SUFFIXES:.c .o

CC=gcc

SRCS=test.c

OBJS=$(SRCS:.c=.o)

EXEC=libtest.so

all:$(OBJS)

$(CC) -shared -o $(EXEC) $(OBJS)

.c.o:

$(CC) -Wall -g -fPIC -o $(@) -c $<

clean:

rm -f $(OBJS)

rm -f core*

make编译链接test.c文件,结果:

xin@xin-Lenovo-V3000:~/code/test1$ ls

makefile test.c test.h

xin@xin-Lenovo-V3000:~/code/test1$ make

gcc -Wall -g -fPIC -o test.o -c test.c

gcc -shared -o libtest.so test.o

xin@xin-Lenovo-V3000:~/code/test1$ ls

libtest.so makefile test.c test.h test.o

生成libtest.so文件。

(3)SO文件使用方法

(1).bash_profile添加export LD_LIBRARY_PATH=LDLIBRARYPATH:.或者将.so文件放入系统目录/usr/lib/(不推荐,这样很可能误删,搞混系统库文件),之所以添加exportLDLIBRARYPATH=LD_LIBRARY_PATH:.是为了,调用.so文件时候于.so文件位置无关。

# .bash_profile

# Get the aliases and functions

if [ -f ~/.bashrc ]; then

. ~/.bashrc

fi

# User specific environment and startup programs

PATH=$PATH:$HOME/bin:.

export PATH

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.

一定注意拼写,宝宝曾经犯过一些关于拼写错误,找了很长时间。

然后:wq退出,还要让.bash_profile生效,输入语句:

xin@xin-Lenovo-V3000:~$ . .bash_profile

注意:两个小点之间有一个空格。

(2)在别的c文件(或者cpp)中使用so文件,一定要包含so文件的头文件。

test.h文件:

#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

这里采用了混合编程,否则g++编译会发生错误。

(3).cpp文件为:

#include

#include

#include "test.h"

int main(){

printf("max=%d\n",max(4,5));

printf("add=%d\n",add(4,5));

return 0;

}

(4).cpp的makefile文件编写:

.SUFFIXES:.cpp .o

CC=g++

SRCS=a.cpp

OBJS=$(SRCS:.cpp=.o)

EXEC=a

start:$(OBJS)

$(CC) -o $(EXEC) $(OBJS) -L. -ltest

.cpp.o:

$(CC) -Wall -g -o $(@) -c $<

clean:

rm -f $(OBJS)

rm -f core*

其中:g++链接时-L参数指明so文件存放路径,-l参数指明so文件名。

(CC)−o(EXEC) $(OBJS) -L. -ltest

-L:在当前路径寻找so文件;

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

(5)make结果:

xin@xin-Lenovo-V3000:~$ cd code/test1

xin@xin-Lenovo-V3000:~/code/test1$ make

g++ -Wall -g -o a.o -c a.cpp

g++ -o a a.o -L. -ltest

xin@xin-Lenovo-V3000:~/code/test1$ ls

a a.cpp a.o libtest.so makefile test.c test.h test.o

xin@xin-Lenovo-V3000:~/code/test1$ ./a

max=5

add=9

如果我们.h文件不采用混合编译,而简单的这样写:

#ifndef TEST_H

#define TEST_H

int max(int a,int b);

int add(int a,int b);

#endif // TEST_H

当我们make时候就会:

xin@xin-Lenovo-V3000:~/code/test1$ make

g++ -Wall -g -o a.o -c a.cpp

g++ -o a a.o -L. -ltest

a.o:在函数‘main’中:

/home/xin/code/test1/a.cpp:5:对‘max(int, int)’未定义的引用

/home/xin/code/test1/a.cpp:6:对‘add(int, int)’未定义的引用

collect2: error: ld returned 1 exit status

makefile:7: recipe for target 'start' failed

make: *** [start] Error 1

因为我们编写的.so文件是c编写的,如果cpp文件调用,必须用extern “C”关键字修饰,表示用c的方法识别这个函数。