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

(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的方法识别这个函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值