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需使用相同架构 [2025-08-07 21:25:48 | AI写代码神器 | 1042点数解答]
- 帮我写一个批处理文件,内容如下: 1、如果在"参数表.xlsx"a列中的值找到与"文件.txt"中相同的值,则把此行中p=的值改为"参数表.xlsx"中c列对应的值; 2、如果在"参数表.xlsx"a列中的值找到与"文件.txt"中相同的值,则把此行中t=的值改为"参数表.xlsx"中b列对应的值; 3、如果在"参数表.xlsx"a列中的值找到与"文件.txt"中相同的值,则把此行中s=的值改为"参数表.xlsx"中d列对应的值; 如: 参数表.xlsx中a列a1,a2,a3;b列1.5,2,3;c列为10,20,30;d列100,101,102; 文件.txt中的行 1:l p[54:a1] 2000mm/sec cnt100 spot[sd=1,p=25,t=2.0,s=10,ed=1]; 2:l p[57:a2] 2000mm/sec cnt100 spot[sd=1,p=25,t=2.0,s=11,ed=1]; 3:l p[67:a3] 2000mm/sec cnt100 spot[sd=1,p=25,t=2.0,s=12,ed=1]; 文件.txt修改后为 1:l p[54(811点数解答 | 2024-12-05 12:58:37)259
- 帮我写一个批处理文件,内容如下: 1、如果在"参数表.xlsx"a列中的值找到与"文件.txt"中相同的值,则把此行中p=的值改为"参数表.xlsx"中c列对应的值; 2、如果在"参数表.xlsx"a列中的值找到与"文件.txt"中相同的值,则把此行中t=的值改为"参数表.xlsx"中b列对应的值; 3、如果在"参数表.xlsx"a列中的值找到与"文件.txt"中相同的值,则把此行中s=的值改为"参数表.xlsx"中d列对应的值; 参数表.xlsx中a列a1,a2,a3;b列1.5,2,3;c列为10,20,30;d列100,101,102; 文件.txt数据 1:l p[54:a1] 2000mm/sec cnt100 spot[sd=1,p=25,t=2.0,s=10,ed=1]; 2:l p[57:a2] 2000mm/sec cnt100 spot[sd=1,p=25,t=2.0,s=11,ed=1]; 3:l p[67:a3] 2000mm/sec cnt100 spot[sd=1,p=25,t=2.0,s=12,ed=1]; 文件.txt修改后数据 1:l p[54:a1(531点数解答 | 2024-12-05 13:20:42)255
- 帮我写一个批处理文件,内容如下: 1、如果在"参数表.xlsx"a列中的值找到与"文件.txt"中相同的值,则把此行中p=的值改为"参数表.xlsx"中c列对应的值; 2、如果在"参数表.xlsx"a列中的值找到与"文件.txt"中相同的值,则把此行中t=的值改为"参数表.xlsx"中b列对应的值; 3、如果在"参数表.xlsx"a列中的值找到与"文件.txt"中相同的值,则把此行中s=的值改为"参数表.xlsx"中d列对应的值; 参数表.xlsx中a列a1,a2,a3;b列1.5,2,3;c列为10,20,30;d列100,101,102; 文件.txt数据 1:l p[54:a1] 2000mm/sec cnt100 spot[sd=1,p=25,t=2.0,s=10,ed=1]; 2:l p[57:a2] 2000mm/sec cnt100 spot[sd=1,p=25,t=2.0,s=11,ed=1]; 3:l p[67:a3] 2000mm/sec cnt100 spot[sd=1,p=25,t=2.0,s=12,ed=1]; 文件.txt修改后数据 1:l p[54:a1(495点数解答 | 2024-12-05 13:22:26)233
- import win32com.client import os def excel_to_pdf(input_file, output_file): # 确保输入文件存在 if not os.path.exists(input_file): raise FileNotFoundError(f"文件 {input_file} 不存在") # 创建 Excel 应用程序实例 excel = win32com.client.Dispatch("Excel.Application") excel.Visible = False # 不显示 Excel 窗口 try: # 打开 Excel 文件 wb = excel.Workbooks.Open(input_file) # 设置页面布局为 A4 横向 for ws in wb.Worksheets: ws.PageSetup.Orientation = 2 # 2 表示横向 (507点数解答 | 2025-03-10 15:48:12)197
- 作为linux开发,调用 schedule()进行进程切换的方式有几种?(309点数解答 | 2023-11-09 18:41:19)471
- 请构建一个开发项目,列出基本的项目,文件,路径,编译设置,windows环境。要求:1、有基本的目录结构 2、有文件,库路径设置 3、有编译脚本设置(gcc、cmakelist、makefile)(459点数解答 | 2024-11-02 20:38:01)179
- 借助行程编码获取多个region中,面积最大region的面积。要求: 1.使用halcon环境 2.使用darw *算子绘制不少于3个region3.获取每个region的行程编码4.利用行程编码的数据求解每个region面积[a1]5.用area center算子提取region面积[a2]6.使用write tuple算子将面积最大的a1,a2写到“面积.txt"文件(527点数解答 | 2024-11-03 08:48:03)133
- 借助行程编码获取多个region中,面积最大region的面积。要求: 1.使用halcon环境 2.使用darw *算子绘制不少于3个region3.获取每个region的行程编码4.利用行程编码的数据求解每个region面积[a1]5.用area center算子提取region面积[a2]6.使用write tuple算子将面积最大的a1,a2写到“面积.txt"文件(606点数解答 | 2024-11-03 08:49:05)146
- 借助行程编码获取多个region中,面积最大region的面积。要求: 1.使用halcon环境 2.使用darw *算子绘制不少于3个region3.获取每个region的行程编码4.利用行程编码的数据求解每个region面积[a1]5.用area center算子提取region面积[a2]6.使用write tuple算子将面积最大的a1,a2写到“面积.txt"文件(888点数解答 | 2024-11-03 08:49:18)330
- 将当前目录的文件名输入到当前目录的一个访问"url.txt"文件,一行一个文件名。,语言方向:Python(130点数解答 | 2024-12-25 11:15:01)238
- 使用 python 实现将当前目录中的文件名字输入到"url.txt"文件(每行一个文件名),语言方向:Python(127点数解答 | 2024-12-25 11:19:25)150
- 输入起始IP地址和结束数字。 根据范围获取IP地址、MAC地址和计算机名。 显示用途和帮助说明,并显示正在获取的IP地址。 将结果按照序号、IP地址(标记本机地址)、MAC地址、计算机名用2个空格分隔排列,保存为 IP地址.txt 文件。(456点数解答 | 2025-02-28 23:43:19)114