SO文件的编写,编译,使用方法
2016-08-23 09:57
507 查看
(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<stdio.h> #include<stdlib.h> #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的方法识别这个函数。
相关文章推荐
- aix中使用xlc编译生成动态链接库(shared object)(.so)文件的方法
- 最简单 的入门且最直观的Makefile和.so文件编译链接使用方法
- aix中使用xlc编译生成动态链接库(shared object)(.so)文件的方法
- cygwin+android ndk编译供给Android使用的.so库文件
- mpi编译Boost生成so文件出错:failed gcc.link.dll解决方法
- Linux 下 Eclipse编译找不到so库文件的解决方法
- 一个使用FFmpeg库读取3gp视频的例子-Android中使用FFmpeg媒体库(三).so文件编译过程问题的解决
- 使用javac,手动编译一个java文件的方法
- 使用NDK编译C/C++为.so文件
- android SDK使用cygwin编译.so文件
- Linux下使用QT编写和调用动态链接库(.so文件)
- JNI 编写动态链接库 HelloNative 详细过程(也即用Java和C在Linux下动态生成并使用so文件过程)
- 如何编写Build对文件手机软件的编译--使用antenna和ant
- ffmpeg2.6.2在Ubuntu下使用NDK编译成.so文件
- coco2dx编译so文件出错解决方法
- vs2005中Def文件的使用方法(DLL编写无法找到函数名称)
- JNI 使用总结 (JAVA 调用C语言编写的DLL/SO/SL文件)
- 黑马程序员_ADO.Net(配置文件的两种写法与使用方法,手动编写SqlHelper类)
- 编译时所需的文件(包含头文件和库文件)使用方法