娱乐公司网站建站背景介绍,西陆网,临沂市建设安全管理网站,安徽海绵城市建设协会网站在windows环境下#xff0c;我们通常在IDE如VS的工程中开发C项目#xff0c;对于生成和使用静态库#xff08;*.lib#xff09;与动态库#xff08;*.dll#xff09;可能都已经比较熟悉#xff0c;但是#xff0c;在linux环境下#xff0c;则是另一套模式#xff0c;… 在windows环境下我们通常在IDE如VS的工程中开发C项目对于生成和使用静态库*.lib与动态库*.dll可能都已经比较熟悉但是在linux环境下则是另一套模式对应的静态库*.a与动态库*.so的生成与使用方式是不同的。刚开始可能会不适应但是用多了应该会习惯这种使用因为步骤上并没有VS下配置那么繁琐。下面就分别总结下linux下生成并使用静态库与动态库的方法由于是C项目所以编译器用的g但是与gcc的使用是相通的 首先是准备工作把我们需要封装成库文件的函数的头文件与源文件写好如下 //myAPI.h
int ADD(int a, int b);
int MINUS(int a, int b); //myAPI.cpp
#include myAPI.hint ADD(int a, int b){return a b;
}int MINUS(int a, int b){return a - b;
} 接下来准备一个测试用的主函数源文件 //main.cpp
#include myAPI.h
#include iostreamint main(){std::cout 1 1 ADD(1, 1) std::endl;std::cout 1 - 1 MINUS(1, 1) std::endl;return 0;
} 重要说明: linux下用生成静态库的命令 ar 处理 myAPI.o 文件生成静态库文件生成的库文件应遵循规范及linux下库文件加“lib”前缀。 编译/链接生成时,也要注意,目标文件/库文件之间有依赖关系,则需要把被依赖文件放到后面(g6.x),才能编译, 不然可能报错 找不到变量函数/ 未定义的引用 undefined reference to. 贴上Makefile,有注解: all: main-1 main-2 main-a main-so main-so2main-1: myAPI.cpp main.cpp myAPI.hg -o main-1 myAPI.cpp main.cppecho main-1 done. 直接编译省略显示编译.o文件echomain-2: main.cpp myAPI.og -o main-2 myAPI.o main.cppecho main-2 done. 显示编译.o文件echomain-a: libmyAPI.ag -o main-a main.cpp libmyAPI.aecho main-a done. 使用.a静态库文件 链接生成程序echomain-so: libmyAPI.sog -o main-so main.cpp ./libmyAPI.soecho main-so done. 直接使用.so动态库文件(需要带路径,运行时直接使用此路径) 链接生成程序echomain-so2: libmyAPI.sog -o main-so2 main.cpp -L. -lmyAPIecho main-so2 done. 让g自动在当前目录(.表示当前目录,或./)查找.so动态库文件 链接生成程序echo 但运行时默认到/usr/lib目录查找,,或运行前设置环境变量 LD_LIBRARY_PATH 为动态库的路径echomyAPI.o: myAPI.cpp myAPI.hg -c myAPI.cppecho myAPI.o done. 编译.o文件echolibmyAPI.a: myAPI.oar crv libmyAPI.a myAPI.oecho libmyAPI.a done. 编译.a静态库文件echolibmyAPI.so:g -fPIC -c myAPI.cppg -shared -o libmyAPI.so myAPI.oecho libmyAPI.so done. 编译.so动态库文件,需要 .o文件编译时加选项 -fPICecho 或者 直接编译动态库:echo g -shared -fPIC -o libmyAPI.so myAPI.cppecho#或者 直接编译动态库:
#libmyAPI.so:
# g -shared -fPIC -o libmyAPI.so myAPI.cpp
#clean:rm -f *.o *.a *.so main-* 最后运行程序: [rootlzp test2]# ./main-1
1 1 2
1 - 1 0
[rootlzp test2]# ./main-2
1 1 2
1 - 1 0
[rootlzp test2]# ./main-a
1 1 2
1 - 1 0
[rootlzp test2]# ./main-so
1 1 2
1 - 1 0
[rootlzp test2]# ./main-so2
./main-so2: error while loading shared libraries: libmyAPI.so: cannot open shared object file: No such file or directory 可以看到 main-so直接运行了,但是 main-so2 运行出错了,找不到动态库,需要把动态库放到/usr/lib目录; 或者使用LD_LIBRARY_PATH环境变量后可以直接运行 [rootlzp test2]# LD_LIBRARY_PATH./
[rootlzp test2]# ./main-so2
./main-so2: error while loading shared libraries: libmyAPI.so: cannot open shared object file: No such file or directory
[rootlzp test2]# LD_LIBRARY_PATH./ ./main-so2
1 1 2
1 - 1 0 PS:但是在 G 6.x版本下直接运行main-so2不出错,,以上是G4.X版本编译的 在项目开发过层中尽量让lib是垂直关系避免循环依赖越是底层的库越是往后面写 例如: g ... obj($?) -l(上层逻辑lib) -l(中间封装lib) -l(基础lib) -l(系统lib) -o $ 这样写可以避免很多问题这个是在搭建项目的构建环境的过程中需要考虑 清楚地在编译和链接上浪费太多的生命不值得 推荐一本书,写的很深刻《程序员的自我修养——链接、装载与库》 [参考: http://www.tuicool.com/articles/m67z2u2; http://blog.chinaunix.net/uid-24352482-id-3199452.html] [参考: http://www.cnblogs.com/little-ant/p/3398885.html]转载于:https://www.cnblogs.com/lzpong/p/5776728.html