C++如何调用动态链接库(DLL/SO)?(代码示例)
技术百科
尼克
发布时间:2025-12-22
浏览: 次 Windows用LoadLibrary+GetProcAddress,Linux用dlopen+dlsym实现运行时动态加载;需注意函数导出(__declspec(dllexport)/__attribute__((visibility("default"))))、类型安全调用、跨平台封装、路径与符号可见性、内存管理边界等关键点。
Windows 下用 LoadLibrary + GetProcAddress,Linux 下用 dlopen + dlsym。核心是运行时加载、获取函数地址、类型安全调用。
Windows:用 LoadLibrary 加载 DLL
需要头文件 #include windows.h>,DLL 导出函数需用 __declspec(dllexport)(编译 DLL 时),调用方用 typedef 声明函数指针类型,再通过 GetProcAddress 获取地址。
示例(调用一个 int add(int, int) 函数):
- 先定义函数指针类型:typedef int (*AddFunc)(int, int);
- 加载 DLL:HMODULE hDll = LoadLibrary(L"mylib.dll");
- 获取函数地址:AddFunc add = (AddFunc)GetProcAddress(hDll, "add");
- 检查并调用:if (add) { int r = add(3, 5); }
- 用完释放:FreeLibrary(hDll);
Linux:用 dlopen 加载 SO
需链接 -ldl,头文件 #include
示例(同样调用 add 函数):
- 定义函数指针:typedef int (*AddFunc)(int, int);
- 打开共享库:void* handle = dlopen("./libmylib.so", RTLD_LAZY);
- 获取符号:AddFunc add = (AddFunc)dlsym(handle, "add");
- 检查错误:const char* err = dlerror(); if (err) { /* 处理 */ }
- 调用后关闭:dlclose(handle);
跨平台封装小技巧
可用宏隔离差异,让业务代码统一:
- 定义统一句柄类型:#if
def _WIN32
using LibHandle = HMODULE;
#else
using LibHandle = void*;
#endif - 封装加载/查找/卸载函数,内部按平台分支处理
- 务必检查返回值(NULL / nullptr / INVALID_HANDLE_VALUE),避免崩溃
- 函数签名必须严格一致,C++ 重载名会 mangling,DLL/SO 中导出推荐用 extern "C" 防止
常见坑和注意点
- DLL 路径问题:Windows 默认只在系统路径、当前目录、PATH 中找;可用绝对路径或 SetDllDirectory
- SO 依赖:用 ldd libmylib.so 查依赖,确保运行时能解析
- 类对象不能直接跨模块传递:只传 C 风格函数或纯虚接口(如 COM/抽象基类 + 工厂函数)
- 内存管理:谁分配谁释放;避免在 DLL 中 new、在主程序中 delete(可能用不同堆)
基本上就这些。不复杂但容易忽略路径、符号可见性、调用约定和内存边界。
# 加载
# 小技巧
# windows
# 用完
# 只在
# 见性
# win
# linux
# default
# 对象
# 堆
# c++
# if
# int
# void
# 主程序
# 指针
# 接口
# delete
# NULL
# lsp
# 封装
# 头文件
# cad
# typedef
# extern
# 指针类型
# char
# const
# 句柄
# include
# 内存管理
# using
# 中找
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- php错误怎么开启_display_errors与
- Win11怎么开启游戏模式_Win11优化游戏帧数
- Win11怎么把图标拖到任务栏_Win11固定应用
- c++怎么操作redis数据库_c++ hired
- MAC怎么一键隐藏桌面所有图标_MAC极简模式切换
- Django 测试数据库表缺失与字段未创建问题的完
- 如何在 Go 同包不同文件中正确引用结构体
- C++ static_cast和dynamic_c
- Win11怎么关闭专注助手 Win11关闭免打扰模
- SAX解析器是什么,它与DOM在处理大型XML文件
- Windows笔记本无法进入睡眠模式怎么办?(电源
- Win11怎么设置任务栏透明_Windows11使
- 如何在 Windows 11 中使用 AlomWa
- php转mp4怎么设置帧率_调整php生成mp4视
- Win11怎样安装微信开发者工具_Win11安装开
- Win11怎么关闭触控板_Win11笔记本禁用触摸
- 如何使用Golang table-driven基准
- Win11视频默认播放器怎么改_Win11关联第三
- Python日志系统设计与实现_高可观测性架构实战
- Python对象生命周期管理_创建销毁解析【教程】
- Win11怎么设置ipv4地址_Windows 1
- 如何在 ACF 中正确更新嵌套多层 Group 字
- Win10怎么关闭自动更新错误弹窗_Win10策略
- Windows10系统怎么查看系统版本_Win10
- php订单日志怎么在swoole写_php协程sw
- Win11时间格式怎么改成12小时制 Win11时
- 新手学PHP架构总混淆概念咋办_重点梳理【教程】
- Ajax提交表单PHP怎么接收_处理Ajax发送的
- Go 中 := 短变量声明的类型推导机制详解
- php中常量能用::访问吗_类常量与作用域操作符使
- Win11怎么设置快速访问主页_Windows11
- 如何在Golang中使用time处理时间_Gola
- Win11怎样彻底卸载自带应用_Win11彻底卸载
- Win11怎么关闭系统推荐内容_Windows11
- Windows怎样拦截WPS弹窗广告_Window
- Go语言中CookieJar的持久化机制解析:内存
- Windows蓝屏BAD_POOL_HEADER故
- php中::能用于接口静态方法吗_接口静态方法调用
- php怎么下载安装后设置错误日志_phpini l
- 如何在Golang中实现基础配置管理功能_Gola
- Golang如何避免指针逃逸_Golang逃逸分析
- Python爬虫项目实战教程_Scrapy抓取与存
- Win10怎样卸载iTunes_Win10卸载iT
- 如何使用Golang实现基本类型比较_Golang
- 如何在Golang中使用内置函数_Golangle
- Win11讲述人怎么关闭_Win11误触开启语音朗
- 如何减少Golang内存碎片化_Golang内存分
- 如何高效获取循环末次生成的 NumPy 数组最后一
- Win11怎么看电池循环次数_Win11笔记本电池
- Win11怎么关闭自动更新 Win11永久关闭系统

def _WIN32
QQ客服