so库生成和用法汇总
函数名 | 功能描述 |
---|---|
dlopen | 打开对象文件,使其可被程序访问 |
dlsym | 获取执行了 dlopen 函数的对象文件中的函数的地址 |
dlerror | 该函数没有参数,它会在发生前面的错误时返回一个字符串,同时将其从内存中清空; 在没有错误发生时返回 NULL, |
dlclose |
关闭目标文件。如果无需再调用共享对象的话,应用程序可以调用该方法来通知操作系统不再需要句柄和对象引用了。它完全是按引用来计数的,所以同一个共享对象的多个用户相互间不会发生冲突(只要还有一个用户在使用它,它就会待在内存中)。任何通过已关闭的对象的 |
一、so库生成:
新建一个sort.c文件,写排序函数
使用gcc -o libsort.so -fPIC -shared sort.c
产生libsort.so库。
void InsertSort(int* a,int len)
{
int begin = 1;
int i = 0;
while(begin < len)
{
int key = a[begin];
for(i = begin-1;i>=0;i--)
{
if(a[i]<=key)
{
a[i+1] = key;
break;
}
a[i+1] = a[i];
}
if(i<0)
a[0] = key;
begin++;
}
}
二、.so库有两种调用方法:
1.编译过程中连接到可执行程序
2.用dlopen()动态加载
链接法
新建main.c文件:
使用命令gcc -o main main.c -lsort -L.
编译。
- -L. 表示.so库在当前目录下;
- -lsort表示调用libsort.so库
运行之前,要先使用命令export LD_LIBRARY_PATH=$(pwd)
将当前目录设为gcc搜索.so库的路径,否则是找不到.so库的。
运行./main后输出递增序列,调用成功。
#include <stdio.h>
int main()
{
int i = 0;
int test[]={1,3,5,7,2,4,6,8};
InsertSort(test,8);
for(i=0;i<8;i++)
{
printf("%d,",test[i]);
}
printf("\n");
return 0;
}
dlopen
新建main2.c文件:
使用命令gcc -o main2 main2.c -ldl
编译。动态加载.so库的话需要-ldl。
运行./main2后输出递增序列,调用成功。
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
int main()
{
int i = 0;
int test[]={1,3,5,7,2,4,6,8};
int (*sort)(int*,int);
void *handle = dlopen("./libsort.so",RTLD_LAZY);
if(!handle)
{
printf("dlopen error :%s\n",dlerror());
return -1;
}
sort = dlsym(handle,"InsertSort");
if(!sort)
{
printf("dlsym error :%s\n",dlerror());
}
sort(test,8);
dlclose(handle);
for(i=0;i<8;i++)
printf("%d,",test[i]);
printf("\n");
return 0;
}
三、查看so库的符号表
readelf -s private.so
nm -D private.so
readelf nm objdump 命令详解
https://blog.csdn.net/u014608280/article/details/81948141
https://www.cnblogs.com/foohack/p/4103074.html
四、动态库(.so)隐藏函数名
向客户提供动态链接库(.so)时,有些关键的函数名不希望暴露出去,此时便可以通过gcc的-fvisibility=hidden选项对编译生成的so进行函数符号隐藏,如:LOCAL_CPPFLAGS +=-fvisibility=hidden,执行编译后,使用nm -D xxx.so命令或者readelf --symbols xxx.so查看函数名的确被隐藏,但此时是将所有函数名都隐藏了,那么客户加载so时需要调用的接口函数名(xxx)也会找不到定义,导致编译报undefined reference to xxx错误,所以需要暴露(导出)的函数前应该增加属性__attribute__ ((visibility("default")))设置成可见
五、GNU C++的符号改编机制
例如,全局函数int structure_func(int i, struct test s, double d),其经过符号改编后,函数名变成了_Z14structure_funci4testd。
上一篇: web.xml配置详解
推荐阅读
-
PowerDesigner 建立与SQLSERVER 2005数据库的连接以便生成数据库和从数据库生成到PD中
-
PowerDesigner 建立与数据库的连接以便生成数据库和从数据库生成到PD中(Oracle 10G版)
-
Python二维码生成库qrcode安装和使用示例
-
PowerDesigner 建立与SQLSERVER 2005数据库的连接以便生成数据库和从数据库生成到PD中
-
PowerDesigner 建立与数据库的连接以便生成数据库和从数据库生成到PD中(Oracle 10G版)
-
php生成短网址/短链接原理和用法实例分析
-
详解Android Studio如何导入第三方类库、jar包和so库
-
Android Studio中导入JNI生成的.so库的实现方法
-
使用gd库实现php服务端图片裁剪和生成缩略图功能分享
-
对python插入数据库和生成插入sql的示例讲解