0
点赞
收藏
分享

微信扫一扫

三子棋(C 语言)

王栩的文字 2024-10-15 阅读 25

1.vs2022 生成动态库dll

要创建一个生成dll的工程,包含头文件和源文件。

微软官方教程演练

#ifdef MATHLIBRARY_EXPORTS
#define MATHLIBRARY_API __declspec(dllexport)
#else
#define MATHLIBRARY_API __declspec(dllimport)
#endif

宏定义中的意思记录一下:
如果是打包输出MATHLIBRARY,那么久dllexport,否则dllimport。

之后就是点击生成按钮,会在本地文件中找到dll库。

2.从外部查看dll内容

用到的是VS自带的dumpbin.exe工具,可以在终端中用命令行调用。

PS D:\cpp\dll_demo\Dll1\x64\Release> dumpbin.exe /exports .\Dll1.dll
Microsoft (R) COFF/PE Dumper Version 14.40.33811.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file .\Dll1.dll

File Type: DLL

  Section contains the following exports for Dll1.dll

    00000000 characteristics
    FFFFFFFF time date stamp
        0.00 version
           1 ordinal base
           4 number of functions
           4 number of names

    ordinal hint RVA      name

          1    0 00001080 fibonacci_current = fibonacci_current
          2    1 00001090 fibonacci_index = fibonacci_index
          3    2 00001010 fibonacci_init = fibonacci_init
          4    3 00001030 fibonacci_next = fibonacci_next

  Summary

        1000 .data
        1000 .pdata
        1000 .rdata
        1000 .reloc
        1000 .rsrc
        1000 .text

3.DLL隐式加载

隐式加载:需要头文件、lib链接文件和dll库文件。分别负责找声明、编译链接和运行链接。
分三步:
1.属性–>C/C++ --> 附加包含目录中:写入头文件的文件路径。
2.链接器–>输入:写入dll的导入库lib。
3.连接器–>常规:附加库目录。

困扰多年的问题,补充知识:Visual Studio中C++的包含目录、附加包含目录和库目录和附加库目录的区别

4.DLL显式加载

显式加载:只需要dll库文件,公司只给了这个…不可能把源代码和lib给你的。

只需要三步(在代码中实现):
1.加载库文件:HMODULE hModule = LoadLibrary(L"xxxx.dll");
2.将内部的函数传递到函数指针:GetProcAddress();
3.销毁:FreeLibrary(hModule);

案例是继续上述微软教程实现的Demo:

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

typedef void (*FIB_INIT) (const unsigned long long a, const unsigned long long b);
typedef bool (*FIB_NEXT) ();
typedef unsigned long long (*FIB_CURRENT) ();
typedef unsigned (*FIB_INDEX) ();

int main()
{
	HMODULE hModule = LoadLibrary(L"..\\..\\MathLibrary\\x64\\Debug\\MathLibrary.dll");
	if (hModule == NULL) {
		std::cerr << "加载失败" << std::endl;
		return 1;
	}
	
	FIB_INIT fibInit = (FIB_INIT)GetProcAddress(hModule, "fibonacci_init");
	FIB_NEXT fibNext = (FIB_NEXT)GetProcAddress(hModule, "fibonacci_next");
	FIB_CURRENT fibCurrent = (FIB_CURRENT)GetProcAddress(hModule, "fibonacci_current");
	FIB_INDEX fibIndex = (FIB_INDEX)GetProcAddress(hModule, "fibonacci_index");

	if (!fibInit || !fibNext || !fibCurrent || !fibIndex) {
		std::cerr << "无法加载函数" << std::endl;
		return 1;
	}

	fibInit(1, 1);
	// 生成序列中的下一个值
	bool success = true;
	unsigned index = 0;
	do {
		success = fibNext();
		if (success) {
			std::cout << "F(" << fibIndex() << ") = " << fibCurrent() << std::endl;
		}
	} while (success && index++ < 10); // 限制输出以避免无限循环
	FreeLibrary(hModule);

	return 0;
}

在这里插入图片描述
但是显式加载需要知道函数的参数信息,需要了解开发文档或者反编译。但是反编译信息给的太少,还是需要开发文档。

举报

相关推荐

【c语言】三子棋

C语言三子棋

三子棋C语言

三子棋(C语言)

C语言编写三子棋

三子棋 --- C

0 条评论