这段时间在做一个文件分享的小工具,由于计网在讲纯c写socket,索性也就用纯c实现。然后发现c很不方便没有STL…于是又开始实现起一些常用的数据结构。准备打包成动态库,以后调用也方便。在此记录一下方法。
gcc版本和实验平台介绍
- Apple LLVM version 10.0.1 (clang-1001.0.46.4)
- Target: x86_64-apple-darwin18.7.0
- Thread model: posix
源文件目录
.
├── LICENSE
├── README.md
├── arraylist.md
├── doc
│ └── arraylist.md
├── main.out
├── src
│ ├── a.out
│ ├── arraylist
│ │ ├── arraylist.c
│ │ └── arraylist.h
│ ├── common
│ │ ├── struct_common.c
│ │ └── struct_common.h
│ └── main.c
└── target
└── libarraylist.so
5 directories, 12 files
编译步骤
目前只实现了ArrayList的数据结构,一种类泛型的、可自动增长的list结构。实现在src/arraylist/arraylist.c中,头文件在src/arraylist/arraylist.h,还用到了公用的一些工具函数,定义在src/common/struct_common.h中。
我们对arraylist的实现进行编译,命令如下:
gcc src/arraylist/arraylist.c src/common/struct_common.c -fPIC -shared -o target/libarraylist.so
需要注意的是:
-
-shared该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号),不用该标志外部程序无法连接。1
-
-fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。1
-
生成的.so库注意命名规则,需要是lib开头,接上库的名字,再以.so结尾。这样链接这个库的时候才能方便gcc编译。(隐式命名规则)
链接例子
gcc src/main.c -Ltarget -larraylist -o main.out
- -L: 后面接链接库的目录。
- -l: 后面接动态库的名字。(需要符合上面的命名规则)