C++实战:封装资源文件到动态链接库及调用全攻略与注意事项
# C++封装资源文件到动态链接库并调用 ## 创建动态链接库(DLL) 1. 创建DLL项目(以Visual Studio为例): ```cpp // ResourceDLL.h #pragma once #ifdef RESOURCEDLL_EXPORTS #define RESOURCEDLL_API __declspec(dllexport) #else #define RESOURCEDLL_API __declspec(dllimport) #endif extern "C" RESOURCEDLL_API const char* GetResourceData(); extern "C" RESOURCEDLL_API int GetResourceSize(); ``` 2. 实现DLL源文件: ```cpp // ResourceDLL.cpp #include "ResourceDLL.h" #include <Windows.h> // 资源数据 const char resourceData[] = "这是被封装的资源数据"; const int resourceSize = sizeof(resourceData); extern "C" RESOURCEDLL_API const char* GetResourceData() { return resourceData; } extern "C" RESOURCEDLL_API int GetResourceSize() { return resourceSize; } BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } ``` 3. 编译生成DLL文件(ResourceDLL.dll) ## 调用动态链接库 1. 隐式链接方式: ```cpp #include <iostream> #include <Windows.h> // 声明函数指针类型 typedef const char* (*GetResourceDataFunc)(); typedef int (*GetResourceSizeFunc)(); int main() { // 加载DLL HMODULE hDll = LoadLibrary(L"ResourceDLL.dll"); if (!hDll) { std::cerr << "无法加载DLL" << std::endl; return 1; } // 获取函数地址 GetResourceDataFunc getData = (GetResourceDataFunc)GetProcAddress(hDll, "GetResourceData"); GetResourceSizeFunc getSize = (GetResourceSizeFunc)GetProcAddress(hDll, "GetResourceSize"); if (!getData || !getSize) { std::cerr << "无法获取函数地址" << std::endl; FreeLibrary(hDll); return 1; } // 使用函数 const char* data = getData(); int size = getSize(); std::cout << "资源大小: " << size << std::endl; std::cout << "资源内容: " << data << std::endl; // 释放DLL FreeLibrary(hDll); return 0; } ``` 2. 显式链接方式(需要.lib文件): ```cpp #include <iostream> #include "ResourceDLL.h" // 包含DLL头文件 #pragma comment(lib, "ResourceDLL.lib") // 链接库文件 int main() { const char* data = GetResourceData(); int size = GetResourceSize(); std::cout << "资源大小: " << size << std::endl; std::cout << "资源内容: " << data << std::endl; return 0; } ``` ## 使用Windows资源文件(.rc) 1. 创建资源文件: ``` // Resource.rc #include "Resource.h" #define IDR_MYDATA 101 IDR_MYDATA RCDATA "binarydata.bin" ``` 2. 在DLL中访问资源: ```cpp // ResourceDLL.cpp #include "ResourceDLL.h" #include "Resource.h" #include <Windows.h> extern "C" RESOURCEDLL_API const char* GetResourceData() { HRSRC hRes = FindResource(NULL, MAKEINTRESOURCE(IDR_MYDATA), RT_RCDATA); if (!hRes) return nullptr; HGLOBAL hData = LoadResource(NULL, hRes); if (!hData) return nullptr; return (const char*)LockResource(hData); } extern "C" RESOURCEDLL_API int GetResourceSize() { HRSRC hRes = FindResource(NULL, MAKEINTRESOURCE(IDR_MYDATA), RT_RCDATA); if (!hRes) return 0; return SizeofResource(NULL, hRes); } ``` 我在以往的开发过程中,碰到过以下几点需要格外小心处理的地方: 1. DLL导出函数使用extern "C"避免名称修饰问题 2. 资源文件路径需要正确设置,确保编译时能找到 3. 32位和64位DLL不兼容,调用方和DLL需使用相同架构 ######[AI写代码神器 | 1042点数解答 | 2025-08-07 21:25:48]
- 批处理文件:依据参数表.xlsx精准修改文件.txt中p、t、s值(GPT | 811点数解答 | 2024-12-05 12:58:37)399
- 用批处理和Python实现“参数表.xlsx”与“文件.txt”数据匹配及修改(讯飞星火 | 531点数解答 | 2024-12-05 13:20:42)380
- 批处理文件:依据参数表.xlsx精准修改文件.txt特定参数值(阿里通义 | 495点数解答 | 2024-12-05 13:22:26)358
- Python 利用 win32com 库:将 Excel 转换为 A4 横向 PDF 并单独打印首列(字节豆包 | 507点数解答 | 2025-03-10 15:48:12)319
- Linux 开发:揭秘调用 schedule() 实现进程切换的四大常见方式! (百度文心 | 309点数解答 | 2023-11-09 18:41:19)534
- Java:设计圆类与圆柱体类并计算属性及体积表面积(字节豆包 | 470点数解答 | 2024-10-20 10:03:11)191
- Java 实现矩形与长方体类,精准计算底面积与体积(字节豆包 | 319点数解答 | 2024-10-20 10:25:46)298
- Java 实现矩形与长方体类,轻松计算底面积和体积(字节豆包 | 308点数解答 | 2024-10-20 10:34:27)280
- Java 实现矩形与长方体类:计算底面积与体积的完整代码示例(字节豆包 | 306点数解答 | 2024-10-20 18:34:47)279
- 云南 8 日摄影行程表 HTML 代码优化与逻辑注意点揭秘(字节豆包 | 217点数解答 | 2025-03-09 13:19:03)272
- Java 硬币翻转问题:从错误代码到优化求解及开发注意要点(DeepSeek | 350点数解答 | 2025-10-24 15:10:59)93
- 统计数字出现频率最高的次数的C++代码实现(字节豆包 | 447点数解答 | 2026-04-11 19:50:33)15