动态(显示)加载

1.使用LoadLibrary将指定dll加载进进程,如果不是全路径,则会进行路径搜索

2.使用GetProcAddress获取导出函数的地址和导出变量的地址,然后调用

3.使用FreeLibrary将dll从进程中卸载

4.LoadLibrary会增加引用计数,FreeLibrary会减少引用计数,当计数值为0,才会卸载

5.不同进程加载dll,使用导出变量互不影响,因为使用了写时拷贝

6.当进程加载dll时,物理内存只有一份dll的数据,然后被映射进不同进程,当没有进程使用时,物理内存卸载

def导出

1.连接选项,/DEF:def文件名

2.def格式

EXPORTS
函数1
函数2
函数3
函数4

“DEF 导出”通常是指通过一个 .def 文件来显式指定 DLL(动态链接库)中要导出的符号(函数或变量)。.def 文件是一个文本文件,它定义了导出的函数和变量的名称、序号等信息,允许开发者控制 DLL 中的符号导出方式。

如何使用 .def 文件

在编译 DLL 时,你可以将 .def 文件作为参数传递给编译器或链接器,以便生成具有指定导出的 DLL 文件。

例如,在使用 Microsoft Visual Studio 编译时,可以将 .def 文件添加到项目中,链接器会根据 .def 文件生成 DLL 的导出表。

使用 .def 文件时,开发者可以选择性地指定导出符号的名称、顺序等。如果没有 .def 文件,通常会使用函数声明的名称作为导出符号名。

__declspec(dllexport) 区别

在 C 或 C++ 中,你可以使用 __declspec(dllexport) 来导出函数或变量,而无需使用 .def 文件。例如:

__declspec(dllexport) void Function1();
__declspec(dllexport) int MyVar;

这种方式导出的符号名称与函数名直接绑定,比较简洁。但如果你需要更细粒度的控制(例如指定导出顺序或为符号指定别名),那么使用 .def 文件会更灵活。

MFCdll

MyMFCdll.h

#pragma once

#ifdef MYMFCDLL_EXPORTS
#define MYMFCDLL_API __declspec(dllexport) // 导出符号
#else
#define MYMFCDLL_API __declspec(dllimport) // 导入符号
#endif

class MYMFCDLL_API CMyMFCClass
{
public:
    CMyMFCClass();
    ~CMyMFCClass();

    void ShowMessage();
};

MyMFCdll.cpp

#include "pch.h"
#include "MyMFCdll.h"
#include <afxwin.h> // MFC 包含

CMyMFCClass::CMyMFCClass() {}

CMyMFCClass::~CMyMFCClass() {}

void CMyMFCClass::ShowMessage()
{
    AfxMessageBox(_T("Hello from MFC DLL"));
}

MYMFCDLL_EXPORTS 是一个宏,用来区分 DLL 项目和使用该 DLL 的应用程序。当我们编译 DLL 时,宏 MYMFCDLL_EXPORTS 会被定义,从而确保 __declspec(dllexport) 正确地导出符号。当编译使用该 DLL 的应用程序时,MYMFCDLL_EXPORTS 不会被定义,从而使用 __declspec(dllimport) 来导入符号。

使用 MFC DLL 的应用程序

在应用程序中,我们需要链接 MFC DLL 并调用导出的函数。

#include <afxwin.h>
#include "MyMFCdll.h"

int main()
{
    CMyMFCClass obj;
    obj.ShowMessage(); // 调用 DLL 中的函数
    return 0;
}

Categories:

Tags:

No responses yet

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注