day08 动态链接库

1. extern "C"
指定使用C语言的命名修饰约定
防止C++编译器进行名称重整(name mangling)
使得导出的函数名在DLL中保持原样
便于其他语言(C、C#、VB、Python等)调用
对比示例:
// C++风格(有名称重整)
int __declspec(dllexport) add(int a, int b); // 可能导出为:?add@@YAHHH@Z
// C风格(无名称重整)
extern "C" int __declspec(dllexport) add(int a, int b); // 导出为:add

2. __declspec(dllexport)
Microsoft特定的扩展关键字

指定函数/变量要从DLL中导出

告诉链接器将该符号放入导出表

extern "C" _declspec(dllexport) int my_export1(int a, int b);

 

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
/**
hModule: 当前DLL模块的句柄

ul_reason_for_call: 调用原因(有四种情况)

lpReserved: 保留参数,通常为NUL

四种调用情况:
DLL_PROCESS_ATTACH: 进程加载DLL时调用(首次)

DLL_THREAD_ATTACH: 进程创建新线程时调用

DLL_THREAD_DETACH: 线程结束时调用

DLL_PROCESS_DETACH: 进程卸载DLL时调用

2. 注意事项:
在DllMain中应避免复杂的操作
不要调用可能加载其他DLL的函数
不要创建/终止线程
避免同步操作(如等待锁)
简单的初始化和清理是可以的

最佳实践:
使用单独的初始化函数进行复杂初始化
DllMain中只做最必要的简单操作
考虑使用DisableThreadLibraryCalls()减少线程通知

*/

int my_export1(int a, int b)
{
    return a + b;
}


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;
}

  

替代方法:.def文件

LIBRARY "mywin9dll"
EXPORTS
my_export2 @ 1

  

image

通过隐式的方式导入dll

#pragma once
#include <iostream>
#include <Windows.h>


/*
* 对于dll项目  编译器会产生两个文件,分别是dll lib 
其中dll是动态链接库,保存了所有的代码和数据。
lib是导入库,保存了一些符号和地址的对应信息。不能单独使用,必须与dll 共存,用于动态链接库的隐式链接

通过隐式的方式导入dll

**/
//#pragma comment(lib,"mywin9dll.lib")
extern "C" int my_export1(int a, int b);

  

 

#include "main.h"

int main()
{

	int sum1 = my_export1(9, 5);
	std::cout << sum1 << std::endl;
	return 0;
}

  

通过显式的方式导入dll

#include "main.h"

typedef int (*my_export2)(int a, int b);
int main()
{


	HMODULE hModule = LoadLibraryW(L"mywin9dll.dll");
	my_export2 fun=(my_export2) GetProcAddress(hModule, "my_export2");
	// int sum = my_export2(9, 5);
	std::cout << fun(9,5) << std::endl;
	FreeLibrary(hModule);
	return 0;
}

  

 

 

静态链接库

 

image

 静态链接库的调用,只能使用隐式的调用方式

 

posted @ 2025-12-04 10:00  巨兽~墨菲特  阅读(8)  评论(0)    收藏  举报