小小的石头13 发表于 2022-12-25 17:46

DLL资源的释放

本帖最后由 小小的石头13 于 2022-12-26 14:29 编辑

最近学习到dll这方面, 发现一个不方便的问题, 就是发给朋友还得把exe和dll都发过去, 如果朋友操作不当会引发各种各样的问题
为了解决这个问题, 我就学习了一下资源的释放, 运用工具是vs2022
在此记录一下学习成果,这是一个释放dll文件的例子, 还请大家多指正:
#include <windows.h>
#include "resource.h"
#include <iostream>

using namespace std;
bool CreateMyFile(char * strFilePath, HGLOBAL lpBuffer, DWORD dwSize) {
    DWORD dwWritten;

    // 在指定目录创建文件
    HANDLE hFile = CreateFileA(strFilePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
    if (hFile) {
      // 在刚才创建的文件中写入读取到内存中的资源文件
      WriteFile(hFile, (LPCVOID)lpBuffer, dwSize, &dwWritten, NULL);
    }
    else {
      return false;
    }

    CloseHandle(hFile);
    return true;
}

bool CreateEXE(char* strFilePath, int nResourceID, char* strResourceName) {
    // 查找资源文件返回此资源文件的句柄
    HRSRC hResInfo = FindResourceA(NULL, (LPCSTR)MAKEINTRESOURCE(nResourceID), strResourceName);

    if (!hResInfo) {
      return false;
    }
    // 获取资源文件的大小
    DWORD dwSize = SizeofResource(NULL, hResInfo);

    // 获取指向资源的指针的句柄
    HGLOBAL hResData = LoadResource(NULL, hResInfo);

    if (!hResData) {
      return false;
    }
    // 在堆内存中申请一块dwSize大小的内存空间
    HGLOBAL p = GlobalAlloc(GPTR, dwSize);

    if (!p) {
      return false;
    }

    // LockResource函数用于获取指向hResData的指针
    // 将获取到的指向资源的指针的dwSize大小的内容复制到p指针指向的内存空间
    memcpy(p, LockResource(hResInfo), dwSize);

    // 调用自定义函数, 将p指针指向的空间的内容写入到strFilePath路径中
    bool bRet = CreateMyFile(strFilePath, p, dwSize);

    if (!bRet) {
      GlobalFree(p);

      return false;
    }
    GlobalFree(p);

    return true;
}

int main() {
    char wpath[] = "F:\\mydll.dll";
    char wname[] = "dll";


    CreateEXE(wpath, IDR_DLL1, wname);

    return 0;
}

resource.h头文件:

#define IDR_DLL1                        101

#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE      102
#define _APS_NEXT_COMMAND_VALUE         40001
#define _APS_NEXT_CONTROL_VALUE         1001
#define _APS_NEXT_SYMED_VALUE         101
#endif
#endif


增添一种方式:
这种方式相比于上面的方式, 简单在于不用将资源文件的内存复制一份, 而是直接将资源文件的内容写入到文件中, 降低了错误率, 也更加方便, 推荐使用这种方法:
bool ReleaseFile(char* FileName, DWORD ResId, char* ResType) {
    DWORD Mode = FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE;

    HANDLE hFile = CreateFileA(FileName, GENERIC_WRITE, Mode, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

    if (hFile == INVALID_HANDLE_VALUE) {
      return false;
    }
    HRSRC hrsc = FindResourceA(NULL, MAKEINTRESOURCE(ResId), ResType);
    if (!hrsc) {
      return false;
    }
    HGLOBAL hg = LoadResource(NULL, hrsc);
    if (!hg) {
      return false;
    }
    DWORD dwSize = SizeofResource(NULL, hrsc);
    if (dwSize <= 0) {
      return false;
    }
    DWORD dwWrite = 0;
    WriteFile(hFile, hg, dwSize, &dwWrite, NULL);

    CloseHandle(hFile);

    return dwWrite == dwSize;
}

小小的石头13 发表于 2022-12-26 13:40

bester 发表于 2022-12-26 07:52
话说vs在哪里把dll资源给插入进去,一直没搞懂

新建一个c++项目之后, 在解决方案资源管理器里面有一个资源文件, 然后右键添加资源, 选择导入, 自定义一个资源类型, 然后就可以把自己的dll导入进去了

阿里巴巴董事长 发表于 2023-1-3 11:25

学习一下                     

dadaliya 发表于 2022-12-25 20:13

学习学习一下

rsword1981 发表于 2022-12-25 21:01

学习一下,谢谢大佬

libaogui2022 发表于 2022-12-25 21:24

感谢分享

david33 发表于 2022-12-25 22:31

支持大佬

梓寻sama 发表于 2022-12-25 22:40

感谢大佬整理分享啊!

bester 发表于 2022-12-26 07:52

话说vs在哪里把dll资源给插入进去,一直没搞懂

h512h 发表于 2022-12-26 09:21

谢谢,学习一下

yun520530 发表于 2022-12-26 09:50

学习到了
页: [1] 2
查看完整版本: DLL资源的释放