静态库与动态库
示例代码
//----------------main.cpp---------------
#include<iostream>
using namespace std;
int sum(int a,int b);
int sub(int a,int b);
int main(){
int a = 1;
int b = 2;
cout<<"a+b = "<<sum(a,b)<<endl;
cout<<"a-b = "<<sub(a,b)<<endl;
}
//----------------sum.cpp---------------
int sum(int a,int b){
return a+b;
}
//----------------sub.cpp---------------
int sub(int a,int b){
return a-b;
}
静态库
创建静态库
g++ -c sub.cpp sum.cpp
ar rcs lib.a sum.o sub.o
静态链接
g++ -o prog main.cpp ./lib.a
链接后得到prog 可执行文件。即使删除lib.a也能运行
动态库
创建动态库
g++ -shared -fpic -o lib.so sub.cpp sum.cpp
动态链接
g++ -o prog main.cpp ./lib.so
链接后得到prog 可执行文件。删除lib.so则不能运行
从进程中加载动态库
相关函数
#include<dlfcn.h>
/**
加载动态库,成功返回指向句柄的通用指针,失败返回NULL
filename 为动态库位置
flag = RTLD_LAZY 表示告诉链接器推迟符号解析直到执行来自库中的代码
flag = RTLD_NOW 表示立即解析对外部符号的引用
*/
void* dlopen(const char*filename,int flag);
void* dlsym(void *handle,char*symbol);//symol为需要的库中的符号,成功返回指向符号的指针,失败返回NULL
int dlclose(void *handle);//关闭动态库(如果其他进程没有使用)
const char*dlerror(void);//调用上面三个函数发生的错误
实例
//-----------------------main02.cpp--------------------
#include<iostream>
#include<dlfcn.h>
using namespace std;
int main(){
int a = 1;
int b = 2;
void* handle;
int (*sum)(int,int);
//加载动态库
handle = dlopen("./lib.so",RTLD_LAZY);
if(handle == NULL){
cout<<"共享库打开错误!"<<endl;
return 0;
}
cout<<"共享库打开成功!"<<endl;
//获取符号(sum)解析
sum = reinterpret_cast<int (*)(int,int)>(dlsym(handle,"sum"));
if(sum == NULL){
cout<<"无此符号!"<<endl;
return 0;
}
cout<<"加载成功!"<<endl;
cout<<"a+b = "<<sum(a,b)<<endl;
//卸载共享库,(如果没有其他进程在用)
if(dlclose(handle)<0){
cout<<"卸载失败!"<<endl;
return 0;
}
}
//------------------------sum.cpp---------------------
#ifdef __cplusplus
extern "C" {
#endif
int sum(int a,int b){
return a+b;
}
#ifdef __cplusplus
}
#endif
//------------------------makefile--------------------
prog2:main02.cpp
g++ -rdynamic -o prog2 main02.cpp -ldl
clean:
rm -rf prog2
rm -rf *.o