>
动态库与静态库
Linux:
动态库: // 1
1.vim lib.c
int foo(int a, int b)
{
return a+b;
}
2.gcc -fpic -shared lib.c -o libmylib.so // 动态库编译
3.vim uselib.c
extern int foo(int a, int b);
int main()
{
printf("result is %d\n", foo(1, 2));
}
4.gcc uselib.c -lmylib
-L. // 在当前目录查找动态库, 连接动态库
5.export LD_LIBRARY_PATH=
. // 编译时在当前目录查找动态库(这个环境变量只能在当前窗口使用),
或者将动态库拷贝到usr/lib
6../a.out
制作Linux动态库 : // 2
gcc -c itcast_asn1_der.c -o itcast_asn1_der.o -fPIC (生成与位置无关的代码) ./a.out 运行之后 加载。 延迟载入。
-c itcastderlog.c
-c keymng_msg.c
ar 制作静态库。
gcc -shared -o lib库名.so itcast_asn1_der.o itcastderlog.o keymng_msg.o ----> lib库名.so
2. 动态库使用:
lib库名.so 文件 本身不能执行。
gcc test.c -o a.out -L 指定库所在路径 -l 指定库名 (去掉lib, 去掉.so) -I 指定库所对应的头文件所在目录 ---> a.out
运行 : ./a.out ----》 报错! --》 原因: 动态连接器,找不到加载动态库的目录位置。 ldd a.out 找不到: ===> not found
错误提示:./a.out: error while loading shared libraries: libmymessagereal.so: cannot open shared object file: No such file or directory
-l、-L 给 “连接器” 指定动态库所在位置。
解决: 1. 将自定义的动态库 cp 放到 标准C库所在目录位置;(不推荐)
2. 在可执行文件所在目录位置 执行命令: export LD_LIBRARY_PATH = 库路径; (临时生效)
3. 帮助动态连接器 指定加载 动态库目录位置。 export LD_LIBRARY_PATH = 库路径; 写入 ~/.bash_profile(red hat,
Ubuntu下是~./bashrc), 中
ldd a.out 成功显示动态库位置。 ./a.out 运行。
静态库:
1) gcc -c lib.c lib.o //首先需要将.c文件编译为.o文件
2) ar rcs libmylib.a lib.o
3) gcc uselib.c -o a.out -lmylib -L.
1) 有同名的动态库与静态库时,优先选择动态库,如果要使用静态库加上 -static
2) 通过以下方式可以指定某些库使用静态链接,而某些库使用动态链接
-Wl,-Bstatic -ltest -Wl,-Bdynamic -ltest2
windows动态库 :
动态库创建:
动态库基本常识:
1. win环境下,动态库―― xxx.dll xxx.lib xxx.h
Linux环境下,动态库―― xxx.so xxx.h -L -l 动态链接器 LD_LIBRARY_PATH ldd keymngserver ====> not found
2. 动态库不是一个exe。是系列函数的集合(二进制)。 keyMsg_Encode.c
按某种规范制作,被操作系统加载。 VS -- ldd
如: 111.exe --- aaa.dll
系统在加载111.exe时,检查111.exe运行是否需要额外的动态库。
若需要,则按一定规则加载。找到成功加载,找不到。报错。----指定动态库路径
动态库的制作:
动态库的命名,不要使用中文。
创建时选择.dll生成项目。 但,不能运行。
动态库API函数的导出。
只将用户使用的指定某几个函数从动态库中导出。
使用 __declspec(dllexport) 宏,提示编译器。在编译程序的时候,需特殊处理的函数。
注意: .c 文件 和 .h 文件 均需要添加该宏!! (VS2013 要求)
默认生成的动态库位于上层目录下的 Debug 目录内。
动态库制作结果:
xxxxx.dll 二进制目标函数集,可被操作系统加载
xxxxx.lib 是对dll的描述文件 (包含多少函数,哪些被导出。。。。)
.h 以及以上2个文件 即可为exe执行提供支持。 但提供给用户时, .h中的 __declspec(dllexport) 宏应删除。
动态库调用和调试:
通知VS2013编译器,使用提供的动态库。
将.dll .lib .h三个文件放置在 .c同级目录下。
右键项目“属性”---“配置属性”---“链接器”---“输入”--- “附加依赖项”---下拉菜单“编辑”
----输入【描述dll信息lib文件 xxxxx.lib】
常见错误:
1. 若xxx.lib配置错误,则VS编译器无法找到所用函数。
2. 如若在运行111.exe时,说明操作系统找不到动态库加载路径。
1. 配置PATH 2. 将exe和动态库dll置于同一目录下即可。
- 如果运行时出错可以把dll文件放到上一级目录的debug的目录下
动态库内存释放:
遵循一个原则:谁分配,谁释放。
调用动态库函数分配的内存,也一定要调用动态库函数来释放内存。