0

0

c++如何调用dll动态链接库_c++外部库加载步骤【解析】

冰火之心

冰火之心

发布时间:2026-03-15 20:55:31

|

139人浏览过

|

来源于php中文网

原创

LoadLibrary动态加载DLL并GetProcAddress获取函数指针是Windows下C++运行时调用DLL的核心方法;需注意导出符号匹配、函数指针类型严格一致、错误检查及跨语言接口规范。

c++如何调用dll动态链接库_c++外部库加载步骤【解析】

怎么用 LoadLibrary 加载 DLL 并调用函数

Windows 下 C++ 调用 DLL 的核心路径就是 LoadLibrary + GetProcAddress,不是头文件包含、也不是链接 .lib,那是编译期绑定;动态加载得靠运行时手动取地址。

常见错误是直接写 MyFunc() 调用——这会链接失败或崩溃,因为编译器根本不知道这个符号在哪。必须先拿到函数指针。

  • LoadLibrary 返回 HMODULE,传入 DLL 路径(支持相对路径,但当前工作目录得对)
  • GetProcAddress 拿函数地址,注意:C++ 编译的函数名会被修饰(mangled),导出时得用 extern "C" 或 .def 文件,否则 GetProcAddress(h, "Add") 找不到
  • 函数指针类型必须严格匹配,建议用 typedefusing 定义,比如 typedef int (*AddFunc)(int, int)
  • 调用前务必检查 LoadLibraryGetProcAddress 返回值是否为 NULL,否则一调就崩
auto hDll = LoadLibrary(L"mylib.dll");
if (!hDll) { /* GetLastError() 看具体错因 */ }
auto pAdd = (AddFunc)GetProcAddress(hDll, "Add");
if (!pAdd) { /* 函数名不匹配 or 未导出 */ }
int r = pAdd(3, 5);

为什么 GetProcAddress 找不到函数名

绝大多数“找不到函数”问题不是路径错,而是符号导出没配对。C++ 默认 name mangling,void calc(int) 可能被编译成 ?calc@@YAXH@Z,你传 "calc" 当然查不到。

  • DLL 工程里函数声明加 extern "C",禁用修饰:extern "C" __declspec(dllexport) int Add(int a, int b);
  • 或者用 .def 文件显式导出,内容写 EXPORTS\nAdd,这样不管 C/C++ 都按原名导出
  • dumpbin /exports mylib.dll 确认实际导出名(命令行工具,VS 自带)
  • 64 位程序不能加载 32 位 DLL,反之亦然——GetLastError() 返回 126ERROR_MOD_NOT_FOUND)有时其实是位数不匹配,不是文件不存在

静态链接 .lib 和动态 LoadLibrary 哪个更合适

不是“哪个更好”,是“场景不同”。静态链接(.lib + 隐式加载)启动快、调用快,但 DLL 必须在启动时就存在;LoadLibrary 支持按需加载、热替换、插件化,代价是每次调用多一次指针解引用,且要自己管生命周期。

B12
B12

B12是一个由AI驱动的一体化网站建设平台

下载

立即学习C++免费学习笔记(深入)”;

  • 需要运行时决定加载哪个模块(比如用户选皮肤、算法插件)→ 必须用 LoadLibrary
  • DLL 可能缺失或版本不兼容,程序要降级运行 → 动态加载可捕获失败,走备用逻辑
  • 隐式链接(即项目里加 .lib、声明 __declspec(dllimport))会在进程启动时自动调 LoadLibrary,失败直接弹 Windows 错误框,无法拦截
  • FreeLibrary 不是必须调,进程退出时系统自动释放,但若反复加载/卸载同一 DLL,不调可能泄漏模块句柄(尤其调试时)

跨语言调用 DLL(比如 Python 或 C#)要注意什么

C++ 写的 DLL 被其他语言调,本质还是导出 C 接口。哪怕你内部全用 STL,对外接口也得是纯 C 风格:无类、无引用、无异常、参数和返回值是基本类型或指针。

  • 字符串传参一律用 const char*const wchar_t*,别传 std::string —— 其他语言没法构造或析构它
  • 资源(如分配的内存)谁分配谁释放:如果 DLL 里 malloc 了内存并返回指针,必须提供一个 FreeBuffer 函数,由调用方传回给 DLL 释放,不能让 Python 用 free()
  • 调用约定必须显式指定,比如 __stdcall(Windows API 默认)或 __cdecl(C 默认),Python 的 ctypes 需要显式设 winmode=WINFUNCTYPECALLBACK
  • 结构体对齐要一致,C# 用 [StructLayout(LayoutKind.Sequential, Pack = 1)],C++ 侧也得 #pragma pack(1),否则字段偏移错位

真正麻烦的从来不是加载动作本身,而是 DLL 和主程序之间那条边界上——数据怎么传、内存谁管、错误怎么报、线程怎么安全。这些细节漏一个,就卡在“能加载但一调就崩”上。

相关文章

.dll文件大全
.dll文件大全

.dll文件缺失怎么办?.dll文件在哪下载?不用担心,这里为大家提供了所有的.dll文件下载,无论用户丢失的是什么.dll文件,在这里都能找到。用户保存后,在网盘搜索dll文件全称即可查找下载!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1051

2023.08.02

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

254

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

1131

2024.03.01

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

564

2023.09.20

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

761

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

221

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1570

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

651

2023.11.24

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

69

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 11.4万人学习

C 教程
C 教程

共75课时 | 5.5万人学习

C++教程
C++教程

共115课时 | 22.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号