C语言中dlopen和dlsym的使用方式详解
目录
背景demo生产动态库调用dlopen总结背景
为了是不同的逻辑解耦,一般会把各个业务封装成动态库,然后主逻辑去调用各个插件。这里有个问题是,为什么以前我们都是通过include第三方的头文件,然后通过连接器实现,现在却要利用dlopen呢?考虑以下情况,比如我们要用cublas这个库的sgemm函数。
#include "cublas.h" int main() { cublas:: Mat a, b; cublas::sgemm(a,b); }
我们知道cublas是英伟达提供的,人家每年都要更新动态库的,比如今年更新后,动态库的头文件改了cublas_v2.h, 函数名改为sgemm_v2, 这样一顿操作后,你不仅要升级库,也要修改已经上线的代码,假如这个sgemm函数在你源码中出现了n多次,这将是一个灾难。但是通过下面的方式你就可以避免这个问题:
// func.h #include#include #include // 如果你知道确切的函数返回信息,这个对应下面的cublas_func可以自己写。 #include extern std::once_flag cublas_dso_flag; extern void *cublas_dso_handle; struct DynLoad__add { template inline auto operator()(Args... args) -> DECLARE_TYPE(add, args...) { using cublas_func = decltype(::add(std::declval ()...)) (*)(Args...); std::call_once(cublas_dso_flag, []() { cublas_dso_handle = dlopen("./libcublas.so", RTLD_LAZY); }); static void *p_add = dlsym(cublas_dso_handle, "add"); return reinterpret_cast (p_add)(args...); } }; extern DynLoad__add add; // func.c DynLoad__add add; // main.cc #include #include #include "func.h" int main() { add(2,7)); } 根据上面的代码可以看到,只要你每次修改func.h文件的动态库路劲和函数名就可以了,其他用到的add函数根本不需要再去修改。真是很方便,上面的代码参考paddle的源码:paddle/fluid/platform/dynload/cublas.h
demo
生产动态库
int add(int a,int b) { return (a + b); } int sub(int a, int b) { return (a - b); }
gcc -fPIC -shared caculate.c -o libcaculate.so
调用dlopen
#includevoid *dlopen(const char *filename, int flag); char *dlerror(void); void *dlsym(void *handle, const char *symbol); int dlclose(void *handle);
dlopen是加载动态链接库,flag可以设置不同的模式(RTLD_LAZY 暂缓决定,等有需要时再解出符号, RTLD_NOW 立即决定,返回前解除所有未决定的符号。), dlopen可以返回动态库的句柄,dlsym是获取动态库中的具体函数名或者变量名。dlopen是关闭动态库。
#include#include #include typedef int (*FUNC)(int, int); int main() { void *handle; char *error; FUNC func = NULL; //打开动态链接库 handle = dlopen("./libcaculate.so", RTLD_LAZY); //获取一个函数 *(void **) (&func) = dlsym(handle, "add"); printf("add: %d\n", (*func)(2,7)); //关闭动态链接库 dlclose(handle); }
gcc -rdynamic -o main main.c -ldl
总结
本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!
上一篇:C++重载运算符你真的了解吗
X 关闭
X 关闭
- 15G资费不大降!三大运营商谁提供的5G网速最快?中国信通院给出答案
- 2联想拯救者Y70发布最新预告:售价2970元起 迄今最便宜的骁龙8+旗舰
- 3亚马逊开始大规模推广掌纹支付技术 顾客可使用“挥手付”结账
- 4现代和起亚上半年出口20万辆新能源汽车同比增长30.6%
- 5如何让居民5分钟使用到各种设施?沙特“线性城市”来了
- 6AMD实现连续8个季度的增长 季度营收首次突破60亿美元利润更是翻倍
- 7转转集团发布2022年二季度手机行情报告:二手市场“飘香”
- 8充电宝100Wh等于多少毫安?铁路旅客禁止、限制携带和托运物品目录
- 9好消息!京东与腾讯续签三年战略合作协议 加强技术创新与供应链服务
- 10名创优品拟通过香港IPO全球发售4100万股 全球发售所得款项有什么用处?