Dll 可执行文件的编写与调用

一、Dll 可执行文件的编写

首先我们需要在 VS 创建一个动态链接库(DLL)项目,然后会生成如下代码:

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"

BOOL APIENTRY DllMain( HMODULE hModule,  // 指向 Dll 模块的句柄
                       DWORD  ul_reason_for_call,  // 指示调用 DllMain 的原因
                       LPVOID lpReserved  // 保留参数,忽略
                     )
{
    switch (ul_reason_for_call)
    {
        // 进程加载本 Dll 后执行
        case DLL_PROCESS_ATTACH:
            MessageBoxA(NULL, "Dll 加载成功", NULL, NULL);
            break;

        // 线程被创建后执行
        case DLL_THREAD_ATTACH:
            break;

        // 线程正常退出后执行
        case DLL_THREAD_DETACH:
            break;

        // 进程卸载本 Dll 后执行
        case DLL_PROCESS_DETACH:
            break;
    }
    return TRUE;
}

直接编译即可生成一个最简单的 Dll 可执行文件,那么如果我们想要在 Dll 文件中导出相关函数,那么要怎么操作呢?

我们需要定义一个导出函数声明,并且对这个导出函数进行实现:

extern "C" __declspec(dllexport) void MsgBox(LPCSTR msg, LPCSTR title)
{
    MessageBoxA(NULL, msg, title, NULL);
}

上面的代码中,我们声明并实现了一个 MsgBox 函数,函数中调用了 MessageBoxA 函数。其中,__declspec(dllexport) 修饰符表示该函数用于导出,extern "C" 表示在对该函数进行编译的时候按照 C 语言编译方式进行。

其实除了导出函数外,我们还可以通过 __declspec(dllimport) 修饰符来告诉编译器,被它修饰的函数或变量需要从其他的 Dll 导入,由于 Dll 可执行文件很少用到导入功能,在此不做详述。

二、动态调用 Dll 可执行文件的导出函数

首先,我们需要定义一个函数指针用来接收这个导出函数:

// 定义一个函数指针
typedef void(*PMSGBOX)(LPCSTR msg, LPCSTR title);

然后我们通过 LoadLibrary 函数来动态加载 Dll 可执行文件,并通过 GetProcAddress 函数来从 Dll 可执行文件中获取特定的导出函数:

// 加载 Dll 模块
HMODULE hModule = LoadLibraryA("./console_Dll.dll");
if (hModule)
{
    PMSGBOX pMsgBox = (PMSGBOX)GetProcAddress(hModule, "MsgBox");
    pMsgBox("hello", "msgbox");
}

调用的结果如下:

posted @ 2024-09-02 18:45  lostin9772  阅读(88)  评论(0)    收藏  举报