目录
1 动态库的使用
交付文件是.h和.so文件,同时,告之此so文件适用的平台(跨平台使用时可能会有问题)例如,目标平台: centos 6.8 64bit
//example.cpp文件
#include <stdio.h>
int example(int a, int b)
{
printf("example library: a=%d, b=%d \n", a, b);
return 0;
}
//example.h文件
int example(int a, int b);
使用g++命令来生成动态库。
编译,生成.o文件 (编译选项 ‐fPIC ) g++ ‐c ‐fPIC example.cpp ‐o example.o
链接,生成目标 .so文件 ( 链接选项 ‐shared) g++ ‐shared example.o ‐o libexample.so
(PIC: Position Independent Code位置无关代码)
-shared:告诉g++生成的共享库而不是可执行文件
linux下动态库的规范命名:libxxx.so;前缀 lib;后缀 .so;其中 xxx是库的名称,例如 , libexample.so
使用nm libXXX.so查看库的大概内容
2 交付后如何使用
(1)交付物两个文件,.h文件内容如下:
(2)编写main.cpp文件
//main.cpp
#include "example.h"
int main()
{
example(1,2);
return 0;
}
(3)编译:g++ ‐c main.cpp ‐o main.o 正确
(4)链接:g++ main.o ‐o helloworld ‐L. ‐lexample 错误如下
解决方法,.so文件是直接复制32位系统的,要用64微系统的才可以。看当前系统的位数 shell下输入: getconf LONG_BIT。
正确输出
链接选项说明:
‐lexample 使用libexample.so这个库文件
‐L. 指定库文件的位置,可以指定多个路径 -L. -L/test
程序的运行
操作系统默认从标准位置寻找相应的库 /lib /usr/lib /usr/local/lib
如果没有找到依赖的库文件,则从 LD_LIBRARY_PATH 环境变量里寻找。
也就是说,库文件要么放在标准位置,要么放在 LD_LIBRARY_PATH 指定的位置,才能被操作系统找到。
先使用export命令设置环境变量, 然后再运行程序。
export LD_LIBRARY_PATH=
./helloworld
(5)显示当前环境变量
(6)查看依赖库 readelf ‐d helloworld
至少要知道两个基本的库:
libc.so 标准C库 (ANSI C)
libstdc++.so 标准c++库 (包含STL)
不需要在命令行中指定, g++默认会链接到这两个库
查找libc打头的文件:ls /usr/lib |grep libc 64位的没有查到,ls /usr/lib并没有发现lib...文件,因为64位需要的命令是:ls /usr/lib64 | grep libc
2 Makefile 文件生成动态库
(1)在Makefile中创建动态库
(2)在动态库中使用别的动态库
(3)在动态库中共享class类型
增加编译选项 ‐fPIC,链接选项 ‐shared
① EXE=libexample.so
② g++ ‐shared $(CXX_OBJECTS) ‐o $(EXE)
③ g++ ‐c ‐fPIC ‐MMD $< ‐o $@
文件夹
Makefile
EXE=libexample.so SUBDIR=src CXX_SOURCES =$(foreach dir,$(SUBDIR), $(wildcard $(dir)/*.cpp)) CXX_OBJECTS=$(patsubst %.cpp, %.o, $(CXX_SOURCES)) DEP_FILES =$(patsubst %.o, %.d, $(CXX_OBJECTS)) $(EXE): $(CXX_OBJECTS) g++ -shared $(CXX_OBJECTS) -o $(EXE) %.o: %.cpp g++ -c -fPIC -MMD $< -o $@ -include $(DEP_FILES) clean: rm -rf $(CXX_OBJECTS) $(DEP_FILES) $(EXE) test: echo $(CXX_OBJECTS)
src
example.cpp
#include <stdio.h> #include "example.h" int example(int a, int b) { printf("example library: a=%d, b=%d \n", a, b); return 0; } void Object::Test() { printf("id=%d \n", id); }
example.h
class Object { public: void Test(); int id; }; int example(int a, int b);
make执行以后
文件夹
src
使用.so库文件
main.cpp
#include "src/example.h" int main() { Object obj; obj.id = 123; obj.Test(); return 0; }
4 库的目录结构
(1)Linux下面可能会经常使用各种库,有的是系统自带的库,有的是第三方库。通常它们的目录结构是:
libxxx/
‐ lib/
‐ include/
其中, bin下为程序, lib下为库文件, include为头文件
(2)系统自带库放在
/usr
‐include /
‐lib /
(3)文件放置
头文件:使用编译选项‐I参数来指定 g++ ‐c ‐I /home/mytest/example/include ...
库文件:‐L /home/mytest/example ‐lexample 或 ‐l/home/mytest/example/libexample.so (全路径也是可以的)
(4)使用上面(3)目录结构中的动态库
文件
src
export LD_LIBRARY_PATH=/home/mytest/example/lib 指定路径 mytest自己设置的用户名,例如 /home/w
main.cpp 使用<>
#include <example.h> int main() { example(1,2); return 0; }
Makefile文件
EXE=helloworld SUBDIR=src object #CXXFLAGS:编译选项, LDFLAGS:链接选项 CXXFLAGS += -I/home/mytest/example/include/ LDFLAGS += -L/home/mytest/example/lib -lexample CXX_SOURCES =$(foreach dir,$(SUBDIR), $(wildcard $(dir)/*.cpp)) CXX_OBJECTS=$(patsubst %.cpp, %.o, $(CXX_SOURCES)) DEP_FILES =$(patsubst %.o, %.d, $(CXX_OBJECTS)) $(EXE): $(CXX_OBJECTS) g++ $(CXX_OBJECTS) -o $(EXE) $(LDFLAGS) %.o: %.cpp g++ -c $(CXXFLAGS) -MMD $< -o $@ -include $(DEP_FILES) clean: rm -rf $(CXX_OBJECTS) $(DEP_FILES) $(EXE) test: echo $(CXX_OBJECTS)
(5)比较:“” <>
#include <example.h>
#include "example.h"
<example.h> : 仅从INCLUDE路径里查找此头文件
"example.h" : 先从当前目录下查找,如果不存在,再从INCLUDE路径里查找。
用‐I选项来指定自定义的INCLUDE路径。标准INCLUDE路径 : /usr/include /usr/local/include
参考
阿发你好视频教程