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; ?>
】
相关推荐
- 用Python构建微服务架构实践_FastAPI与
- Win11怎么更改鼠标指针方案_Windows11
- Win11怎么关闭小组件_Win11禁用任务栏天气
- Win11文件扩展名怎么显示 Win11查看文件后
- Windows 10怎么录屏_Windows 10
- mac怎么右键_MAC鼠标右键设置与触控板手势技巧
- Win11输入法切换快捷键怎么改_Windows
- c++如何使用std::bitset进行位图算法_
- Win11怎么关闭专注助手 Win11关闭免打扰模
- PHP cURL GET请求:正确设置请求头与身份
- php485在macos下怎么配置_php485
- Win11怎么更改计算机名_Windows11系统
- Win11怎么查看硬盘型号_Windows 11检
- Win11怎样安装微信开发者工具_Win11安装开
- Windows10如何更改系统字体大小_Win10
- C++中的协变与逆变是什么?C++函数指针与返回类
- c++中如何对数组进行排序_c++数组排序算法汇总
- PHP中require语句后直接调用返回对象方法的
- Win11怎么设置单手模式_Win11触控键盘布局
- C#如何使用XPathNavigator高效查询X
- Win11怎么查看电脑配置_Win11硬件配置详细
- MySQL 中使用 IF 和 CASE 实现查询字
- php下载安装后swoole扩展怎么安装_异步框架
- 如何使用Golang log记录不同级别日志_Go
- Go 语言标准库为何不提供泛型 Contains
- Windows10如何更改日期格式_Win10区域
- c++ stringstream用法详解_c++字
- Win11文件夹预览图不显示怎么办_Win11缩略
- Win10怎么卸载迅雷_Win10彻底卸载迅雷方法
- Win10怎样清理C盘浏览器缓存_Win10清理浏
- VSC怎样在VSC中调试PHPAPI_接口调试技巧
- c++协程和线程的区别 c++异步编程模型对比【核
- TestNG的testng.xml配置文件怎么写
- Win11怎么更改系统语言为中文_Windows1
- Windows如何使用BitLocker To G
- XAMPP 启动失败(Apache 突然停止)的终
- c++的STL算法库find怎么用 在容器中查找指
- Win11开机Logo怎么换_Win11自定义启动
- Win10如何关闭安全中心所有通知 Win10禁用
- php485函数怎么捕获异常_php485错误处理
- Win11怎么禁用键盘自带键盘_Win11笔记本禁
- 如何在Golang中实现CI/CD流水线自动化测试
- 如何使用Golang安装依赖库_管理模块和第三方包
- Python日志系统设计与实现_高可观测性架构实战
- Win10 BitLocker加密教程 Win10
- 如何使用Golang实现文件加密_Golang c
- MAC怎么截图并快速编辑_MAC自带截图快捷键与标
- c# await 一个已经完成的Task会发生什么
- ACF 教程:正确更新嵌套在多层 Group 字段
- Dapper的Execute方法的返回值是什么意思

def _WIN32
QQ客服