so文件在linux中为共享库,与windows下的dll类似。
so文件中的函数可供多个进程调用,最大可能的提供二进制代码的复用。
共享库可以使代码的维护工作大大简化,当修正了一些错误或者添加了新特性的时候,用户只需要获得升级后的so并安装他就可以。
注:即使不同的进程调用同一个so文件,通过共享库并不能实现不同进程间的通讯,因为同一个so被不同进程加载加载到不同的内存空间。
 
 
so文件编译方法
  –so文件的源文件中不需要有main函数,即使有也不会被执行。
  –编译的时候gcc需要加-fPIC选项,这可以使gcc产生与位置无关的代码。
  –连接的时候gcc使用-shared选项,指示生成一个共享库文件。
  –共享库文件名要以lib开头,扩展名为.so。
 
编写so的例子。
int max(int a, int b)
{
if (a > b)
return a;
else
return b;
} int add(int a, int b)
{
return a + b;
}
#ifndef TEST_H_
#define TEST_H_ int max(int a, int b);
int add(int a, int b); #endif /* TEST_H_ */
.SUFFIXES:.c .o

CC=gcc
SRCS=test.c EXEC=libtest.so OBJS=$(SRCS:.c=.o) start:$(OBJS)
$(CC) -shared -o $(EXEC) $(OBJS) .c.o:
$(CC) -g -fPIC -o $@ -c $< clean:
rm -f $(OBJS)
so文件使用方法
  –为了让linux能找到so文件的位置,需要在.bash_profile中添加export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
  –或者将so文件放入linux的系统目录/usr/lib/
  –在c文件中使用so文件,首先需要 #inluce相关h文件。
  –gcc连接时添加 –L参数指明so文件存放路径,-l参数指明so文件名
  –以libtest.so文件在当前路径下举例

gcc -L. -ltest -o a a.o

其中-L.意思为在当前路径下寻找so文件

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

  -o a 意思为编译后的可执行文件名为a

u调用so的例子
#include "test.h"
#include <stdio.h> int main()
{
printf("%d\n", max(, ));
printf("%d\n", add(, ));
return ;
}
.SUFFIXES:.c .o
CC=gcc
SRCS=a.c
EXEC=a
OBJS=$(SRCS:.c=.o)
start:$(OBJS)
$(CC) -L. -ltest -o $(EXEC) $(OBJS)
.c.o:
$(CC) -o $@ -c $<
clean:
rm -f $(OBJS)
当我们在cpp文件中包含test.h文件,用g++链接libtest.so这个库时会报错:

  (.text+0x19): undefined reference to `max(int, int)'

  (.text+0x3d): undefined reference to `add(int, int)'

为了使我们编写的so文件同时可以被C或者C++调用,我们需要修改一下h文件中的函数申明部分。
增加带有__cplusplus的预编译指令。
__cplusplus是c++编译器预定义的一个宏,比如用g++的时候这个宏就被提前定义了
 
 
编写so的例子
  –test.h头文件
如果是c++编译器会默认定义__cplusplus这个宏。
当使用gcc编译的时候产生如下结果:

int max(int a, int b);

int add(int a, int b);

当使用g++编译的时候,产生如下结果:

extern "C"{

int max(int a, int b);

int add(int a, int b);

}

#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_ */
 

最新文章

  1. Centos7 编译安装 Nginx PHP Mariadb Memcached 扩展 ZendOpcache扩展 (实测 笔记 Centos 7.3 + Mariadb 10.1.20 + Nginx 1.10.2 + PHP 7.1.0 + Laravel 5.3 )
  2. Linux_用户级_常用命令(5):rm
  3. IE9以下 placeholder兼容
  4. jface的CheckboxTreeViewer实现单选
  5. Linux进程间通信IPC学习笔记之管道
  6. win2008远程桌面卡顿和上传慢的解决方法
  7. 基于visual Studio2013解决C语言竞赛题之0705矩阵转置
  8. [原创]一种基于Python爬虫和Lucene检索的垂直搜索引擎的实现方法介绍
  9. 第九章——运行tensorflow(Up and Running with TensorFlow)
  10. string find()函数
  11. 【SerpentAI:Python开源游戏智能体开发框架——相比OpenAI Universe可导入自己的游戏、可脱离Docker/VNC运行】
  12. python Flask框架mysql数据库配置
  13. as3.0中如何阻止事件冒泡
  14. How to detect the types of executable files
  15. js中去除字符串两边的空格
  16. CUDA ---- Constant Memory
  17. C# 生成word文档(NPOI)
  18. js设置光标插入文字和HTML
  19. Mermaid 学习
  20. Eclipse下配置Maven

热门文章

  1. net Core 2.1新功能Generic Host(通用主机)
  2. JS计算字符串的长度
  3. jsp有哪些动作?作用分别是什么?
  4. linux swap交换分区说明/管理
  5. 解决 No module named PyQt5.QtWebKitWidgets
  6. [MySQL-MM] 生产环境自动恢复MM中一台M2库的过程,分享从零开始写的自动化重建脚本以及思路 (转)
  7. 用Json Template在Azure上创建Cisco CSR路由器
  8. 使用批处理自动发布IIS站点,基于IIS7及以上
  9. Day2-VIM(四):修改
  10. boost的asio接收单路大数据量udp包的方法