讲师中心 微信公众号
AI工具推荐 视频效率加速

C++怎么调用DLL动态库_C++Windows编程教程【扩展】

风丽吖_1211

风丽吖_1211

发布时间:2026-02-25 12:50:02

|

638人浏览过

|

来源于php中文网

原创

Windows下C++动态加载DLL需用LoadLibrary获取模块句柄,再用GetProcAddress获取函数地址;注意路径为宽字符绝对路径、强制类型转换函数指针、调用后FreeLibrary释放。

c++怎么调用dll动态库_c++windows编程教程【扩展】

怎么用 LoadLibrary 和 GetProcAddress 手动加载 DLL

Windows 下 C++ 调用 DLL 最灵活的方式是运行时动态加载,不依赖 .lib 导入库。核心就是两步:先用 LoadLibrary 拿到模块句柄,再用 GetProcAddress 拿函数地址。

常见错误是传错路径:LoadLibrary 接收的是宽字符字符串(L"xxx.dll"),传窄字符串或没加 L 前缀会返回 NULL;另外路径必须是绝对路径,或确保 DLL 在系统搜索路径(如当前目录、PATH 环境变量所列目录)中。

  • 推荐用 GetFullPathName 或 GetModuleFileName + 目录拼接生成绝对路径,避免相对路径行为不一致
  • 调用完记得用 FreeLibrary 释放,否则 DLL 句柄泄漏,下次 LoadLibrary 可能返回旧句柄而非重新加载
  • GetProcAddress 返回的是 FARPROC,必须强制转成对应函数指针类型,否则调用时参数压栈错位,直接崩溃

示例:

HMODULE hMod = LoadLibrary(L"mylib.dll");
if (!hMod) { /* 处理错误,GetLastError() 看具体原因 */ }
typedef int (*func_t)(int, const char*);
func_t fn = (func_t)GetProcAddress(hMod, "do_work");
if (fn) fn(42, "hello");

为什么 __declspec(dllimport) 链接方式常出 “unresolved external”

这是头文件声明和链接阶段不匹配的典型表现:你写了 __declspec(dllimport),但链接时没提供对应的 .lib,或者 .lib 是用不同编译器/运行时生成的。

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

根本原因是 Windows DLL 导出符号依赖 .lib 文件做“桩跳转”,而这个 .lib 必须和 DLL 编译时完全匹配(同编译器版本、同 CRT 类型:MT/MD、同架构 x64/x86)。

Windows 图片打印
Windows 图片打印

通过 Python 使用 mspaint /pt 在 Windows 上打印图像——绕过 bash 中文路径编码问题。

下载
  • 检查是否漏了 #pragma comment(lib, "mylib.lib") 或项目里没加 .lib 到链接器输入项
  • 确认 DLL 是用 __declspec(dllexport) 正确导出的,且函数名没被 C++ 名字修饰干扰(加 extern "C" 或 .def 文件控制导出名)
  • 如果 DLL 是别人给的,务必确认它提供的是 VS2019 编译的 MD 版本,而你工程设的是 MT,那 .lib 就不能用

调用 C++ 类成员函数从 DLL 导出为什么总失败

直接导出类本身(比如 class __declspec(dllexport) Foo { ... };)在跨模块使用时极不可靠:对象内存布局、vtable 排布、异常处理机制都可能因编译器或设置不同而错乱。

安全做法是只导出 C 风格函数接口,把类封装在 DLL 内部,通过工厂函数创建/销毁实例。

  • 导出两个函数:Foo* create_foo() 和 void destroy_foo(Foo*),且都在 DLL 内实现 new/delete
  • 头文件里只放纯虚接口(struct IFoo { virtual int work() = 0; virtual ~IFoo() = default; };),DLL 返回 IFoo*,调用方只调虚函数
  • 禁止跨 DLL 边界传递 STL 容器、异常、RTTI —— 这些都依赖一致的运行时,一旦不匹配就崩溃或静默错误

Unicode 和 ANSI 字符串传参在 DLL 调用中容易踩哪些坑

Windows API 默认是 Unicode(wchar_t*),但很多老 DLL 用 ANSI(char*)。混用会导致中文全变问号或崩溃,尤其在 GetProcAddress 后手动调用时极易忽略编码差异。

  • 先查清 DLL 函数实际接受的是 LPCSTR 还是 LPCWSTR —— 看它的原始声明或文档,别猜
  • 如果 DLL 是 ANSI 版,但你的程序是 Unicode 工程(默认),必须用 WideCharToMultiByte 转字符串,且指定代码页(通常 CP_ACP 或 CP_UTF8)
  • 不要用 TEXT("...") 或 _T("...") 包裹字符串后直接传给 ANSI 函数:宏展开后仍是宽字符串,指针类型不匹配

最稳妥的做法:统一用 Unicode 编译整个方案,要求 DLL 提供宽字符接口;若做不到,就在调用层做显式转换,并验证转换前后长度和内容。

跨 DLL 的字符串生命周期要自己管好:DLL 不会帮你 malloc 或 delete 你传进去的缓冲区,谁分配谁释放。

相关文章

编程速学教程(入门课程)
编程速学教程(入门课程)

编程怎么学习?编程怎么入门?编程在哪学?编程怎么学才快?不用担心,这里为大家提供了编程速学教程(入门课程),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

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

热门AI工具

更多
DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

创客贴AI

创客贴AI是一款AI图像与设计工具,AI辅助的智能在线设计工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

相关专题

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

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

549

2023.09.22

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

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

1698

2024.03.01

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

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

1878

2023.08.03

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

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

3044

2023.09.04

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

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

6304

2023.10.24

字符串介绍
字符串介绍

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

6329

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

7894

2024.03.22

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

12054

2024.04.29

Postman身份认证怎么配置
Postman身份认证怎么配置

本专题从实际API接口调试场景出发,讲解Postman身份认证的完整配置流程,包括常见认证协议介绍、授权参数设置、访问令牌填写、OAuth 2.0授权及认证失败排查,帮助用户正确完成接口授权与访问验证。

0

2026.11.06

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Python uv官方安装与入门文档
Python uv官方安装与入门文档

共0课时 | 0人学习

Buffalo框架快速入门指南
Buffalo框架快速入门指南

共0课时 | 0人学习

Conan 2 安装指南
Conan 2 安装指南

共0课时 | 0人学习

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

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn