# 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需使用相同架构 [2025-08-07 21:25:48 | AI写代码神器 | 1042点数解答]