so库简介🔗
- so文件在linux中为共享库,与windows下的dll文件类似
- so文件中的函数可以供多个进程调用,最大可能的提供二进制代码的复用
- 共享库可以使代码维护工作大大简化
- so文件不可实现两进程的通信
1,so文件编译方法🔗
- so文件的源文件不需要由main函数,即使有也不会被加载。
- 编译的时候gcc需要加-fPIC选项,这可以使gcc产生与位置无关的代码
- 链接的时候gcc使用-shared选项,指示生成一个共享库文件
- 共享库文件名要以lib开头,拓展名为.so
/*makefile生成共享库*/
.SUFFIXES: .cpp .o
CC=g++
SRCS=test.c
OBJS=$(SRCS:.cpp=.o)
EXEC=libtest.so
all: $(OBJS)
$(CC) -shared -o $(EXEC) $(OBJS)
@echo '-------------ok--------------'
.cpp.o:
$(CC) -Wall -g -fPIC -o $@ -c $<
clean:
rm -f $(OBJS)
rm -f core*
2,so库的使用方法🔗
- 在.bash_profile中添加:export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
- 或者将so文件放在linux的系统目录下
- 在c文件中使用so文件,首先要#include相关.h文件
- gcc链接时添加-L参数指明so文件存放路径,-l参数指明so文件名 /例子:gcc -L. -ltest -o a a.o/
/*makefile编译使用so的c文件编译*/
.SUFFIXES: .cpp .o
CC=g++
SRCS=a.c
OBJS=$(SRCS:.cpp=.o)
EXEC=a
all: $(OBJS)
$(CC) gcc -L. -ltest -o $(EXEC) $(OBJS)
@echo '-------------ok--------------'
.cpp.o:
$(CC) -Wall -g -o $@ -c $<
clean:
rm -f $(OBJS)
rm -f core*
c和cpp混合编译🔗
- 当使用g++编译cpp文件使用gcc生成的so共享库的时候
- 可以把函数加上extern “C” int max(int a,int b);
- 也可以在.h中增加带有__cplusplus的预编译指令,解决混合编程
/*头文件例子*/
#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_*/
综合示例🔗
/*
实现一个so库文件名称为libupper.so,so文件中实现一个函数,函数名
为void upper(const char *src, char *desc),调用update后将
参数src所指向的字符串中所有字符转化为大写字母,结果放入desc字符串
中。分别用C语言编写一个程序test1,调用libupper.so中的upper函
数,用C++语言编写一个程序test2,调用libupper.so中的upper函数。
*/
/*test.h*/
#ifndef TEST_H_
#define TEST_H_
#ifdef __cplusplus
extern "C" {
#endif
void upper(const char *src, char *desc);
#ifdef __cplusplus
}
#endif
#endif
/*test.cpp*/
#include <stdio.h>
#include <stdlib.h>
#include "test.h"
int main()
{
char src[50]="Hello world!";
char desc[50] ="\0";
upper(src,desc);
printf("%s",desc);
return 0;
}
/*libtest.so*/
void upper(const char *src, char *desc)
{
int i=0;
while(src[i]!='\0')
{
if( (src[i] > 'a') && (src[i] < 'z'))
{
desc[i] = src[i] - ('a' - 'A');
}
else
{
desc[i] = src[i];
}
i++;
}
}
备份地址: 【Linux共享库.so的使用】