安装visual studio community 2019,勾选c++桌面开发。参考文章:https://www.cnblogs.com/xmr183729/p/13307265.html;截取前半部分进行操作,用于了解dll的编写(notepad++中编写code)、编译、生成、调用、执行。
dll文件:.cpp → cl 命令 → .obj → Link命令 → .dll
调用dll文件:.cpp → cl命令 → .obj 和.exe
- 1、将cl.exe所在目录追加到PATH环境变量中
- 2、配置cl.exe依赖的环境变量(使用msvc的cl工具编译程序,以及 “fatal error C1034: iostream: 不包括路径集”等问题解决):https://blog.csdn.net/weixin_41115751/article/details/89817123
- 3、cl /c /EHsc dll_nolib.cpp,生成dll_nolib.obj文件
D:\Cpath\studyDir\dllWorld>cl /c /Ehsc dll_nolib.cpp
用于 x64 的 Microsoft (R) C/C++ 优化编译器 19.29.30040 版
版权所有(C) Microsoft Corporation。保留所有权利。
cl: 命令行 warning D9002 :忽略未知选项“/Ehsc”
dll_nolib.cpp
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\include\ostream(746): warning C4530: 使用了 C++ 异常处理程序,但未启用展开语义。请指定 /EHsc
dll_nolib.cpp(12): note: 查看对正在编译的函数 模板 实例化“std::basic_ostream<char,std::char_traits<char>> &std::operator <<<std::char_traits<char>>(std::basic_ostream<char,std::char_traits<char>> &,const char *)”的引用
- 4、Link /dll dll_nolib.obj,生成dll_nolib.dll文件
D:\Cpath\studyDir\dllWorld>Link /dll dll_nolib.obj
Microsoft (R) Incremental Linker Version 14.29.30040.0
Copyright (C) Microsoft Corporation. All rights reserved.
- 5、Cl /EHsc dll_nolib_client.cpp,生成dll_nolib_client.exe文件
D:\Cpath\studyDir\dllWorld>Cl /EHsc dll_nolib_client.cpp
用于 x64 的 Microsoft (R) C/C++ 优化编译器 19.29.30040 版
版权所有(C) Microsoft Corporation。保留所有权利。
dll_nolib_client.cpp
Microsoft (R) Incremental Linker Version 14.29.30040.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:dll_nolib_client.exe
dll_nolib_client.obj
- 6、命令行中执行dll_nolib_client.exe,能看到dll已经被客户端加载过。但是这样仅仅能够将dll加载到内存,不能找到dll中的函数
D:\Cpath\studyDir\dllWorld>dll_nolib_client.exe
Dll被加载到进程中
dll loaded!
dll从进程中卸载
3-6的code
// 文件dll_nolib.cpp
#include <objbase.h>
#include <iostream>
using namespace std;
BOOL APIENTRY DllMain( HANDLE hModule, DWORD dwReason, void* lpReserved)
{
HANDLE g_hModule;
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
cout << "Dll被加载到进程中" << endl;
g_hModule = (HINSTANCE)hModule;
break;
case DLL_THREAD_ATTACH:
cout << "Dll被加载到线程中" << endl;
g_hModule = (HINSTANCE)hModule;
break;
case DLL_THREAD_DETACH:
cout << "dll从线程中卸载" << endl;
g_hModule = (HINSTANCE)hModule;
break;
case DLL_PROCESS_DETACH:
cout << "dll从进程中卸载" << endl;
g_hModule = (HINSTANCE)hModule;
break;
}
return TRUE;
}
// 文件dll_nolib_client.cpp
#include <windows.h>
#include <iostream>
using namespace std;
int main(void){
//加载我们的dll
HINSTANCE hinst = ::LoadLibrary("dll_nolib.dll");
if (NULL != hinst){
cout << "dll loaded!" << endl;
}
return 0;
}
- 7、dumpbin -exports dll_nolib.dll,查看dll中的函数
D:\Cpath\studyDir\dllWorld>dumpbin -exports dll_nolib.dll
Microsoft (R) COFF/PE Dumper Version 14.29.30040.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file dll_nolib.dll
File Type: DLL
Summary
3000 .data
3000 .pdata
11000 .rdata
1000 .reloc
22000 .text
1000 _RDATA
- 8、添加def定义文件来输出函数
D:\Cpath\studyDir\dllWorld>cl /c /EHsc dll_def.cpp
用于 x64 的 Microsoft (R) C/C++ 优化编译器 19.29.30040 版
版权所有(C) Microsoft Corporation。保留所有权利。
dll_def.cpp
D:\Cpath\studyDir\dllWorld>Link /dll dll_def.obj /def:dll_def.def
Microsoft (R) Incremental Linker Version 14.29.30040.0
Copyright (C) Microsoft Corporation. All rights reserved.
dll_def.def(6) : warning LNK4017: DESCRIPTION 语句不支持目标平台;已忽略
正在创建库 dll_def.lib 和对象 dll_def.exp
D:\Cpath\studyDir\dllWorld>dumpbin -exports dll_def.dll
Microsoft (R) COFF/PE Dumper Version 14.29.30040.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file dll_def.dll
File Type: DLL
Section contains the following exports for dll_def.dll
00000000 characteristics
FFFFFFFF time date stamp
0.00 version
1 ordinal base
1 number of functions
1 number of names
ordinal hint RVA name
1 0 00001110 FuncInDll
Summary
3000 .data
3000 .pdata
12000 .rdata
1000 .reloc
22000 .text
1000 _RDATA
D:\Cpath\studyDir\dllWorld>cl /EHsc dll_def_client.cpp
用于 x64 的 Microsoft (R) C/C++ 优化编译器 19.29.30040 版
版权所有(C) Microsoft Corporation。保留所有权利。
dll_def_client.cpp
dll_def_client.cpp(1): warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
Microsoft (R) Incremental Linker Version 14.29.30040.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:dll_def_client.exe
dll_def_client.obj
8的code
// dll_def.cpp
#include <objbase.h>
#include <iostream>
using namespace std;
void FuncInDll(void){
cout<<"FuncInDll is called!"<<endl;
}
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, void* lpReserved){
HANDLE g_hModule;
switch(dwReason){
case DLL_PROCESS_ATTACH:
cout<<"dllMain方法:加载到进程中!"<<endl;
g_hModule = (HINSTANCE)hModule;
break;
case DLL_PROCESS_DETACH:
g_hModule=NULL;
break;
}
return TRUE;
}
// dll_def.def
;
; dll_def module-definition file
;
LIBRARY dll_def.dll
DESCRIPTION '(c)2021 qiaosong'
EXPORTS
FuncInDll @1 PRIVATE
//dll_def_client.cpp
#include <windows.h>
#include <iostream>
using namespace std;
int main(void){
//定义一个函数指针
typedef void (* DLLWITHLIB )(void);
//定义一个函数指针变量
DLLWITHLIB pfFuncInDll = NULL;
//加载我们的dll
HINSTANCE hinst=::LoadLibrary("dll_def.dll");
if (NULL != hinst){
cout<<"dll loaded!"<<endl;
}
//找到dll的FuncInDll函数
pfFuncInDll = (DLLWITHLIB)GetProcAddress(hinst, "FuncInDll");
//调用dll里的函数
if (NULL != pfFuncInDll)
{
(*pfFuncInDll)();
}
return 0;
}
- 9、_declspec(dllexport)导出函数
D:\Cpath\studyDir\dllWorld\V3>cl /c /EHsc dll_declsec.cpp
用于 x64 的 Microsoft (R) C/C++ 优化编译器 19.29.30040 版
版权所有(C) Microsoft Corporation。保留所有权利。
dll_declsec.cpp
D:\Cpath\studyDir\dllWorld\V3>Link /dll dll_declsec.obj
Microsoft (R) Incremental Linker Version 14.29.30040.0
Copyright (C) Microsoft Corporation. All rights reserved.
正在创建库 dll_declsec.lib 和对象 dll_declsec.exp
D:\Cpath\studyDir\dllWorld\V3>Link /dll dll_declsec.obj
Microsoft (R) Incremental Linker Version 14.29.30040.0
Copyright (C) Microsoft Corporation. All rights reserved.
正在创建库 dll_declsec.lib 和对象 dll_declsec.exp
D:\Cpath\studyDir\dllWorld\V3>dir
驱动器 D 中的卷是 工作
卷的序列号是 C14D-581B
D:\Cpath\studyDir\dllWorld\V3 的目录
2021/07/21 22:17 <DIR> .
2021/07/21 22:17 <DIR> ..
2021/07/21 22:15 483 dll_declsec.cpp
2021/07/21 22:17 227,840 dll_declsec.dll
2021/07/21 22:17 710 dll_declsec.exp
2021/07/21 22:17 1,794 dll_declsec.lib
2021/07/21 22:15 178,117 dll_declsec.obj
2021/07/21 22:06 598 dll_declsec_client.cpp
6 个文件 409,542 字节
2 个目录 102,568,783,872 可用字节
D:\Cpath\studyDir\dllWorld\V3>dumpbin -exports dll_declsec.dll
Microsoft (R) COFF/PE Dumper Version 14.29.30040.0
Copyright (C) Microsoft Corporation. All rights reserved.
Dump of file dll_declsec.dll
File Type: DLL
Section contains the following exports for dll_declsec.dll
00000000 characteristics
FFFFFFFF time date stamp
0.00 version
1 ordinal base
1 number of functions
1 number of names
ordinal hint RVA name
1 0 00001110 ?FuncInDll@@YAXXZ
Summary
3000 .data
3000 .pdata
12000 .rdata
1000 .reloc
22000 .text
1000 _RDATA
D:\Cpath\studyDir\dllWorld\V3>cl /EHsc dll_declsec_client_LoadErrorFunc.cpp
用于 x64 的 Microsoft (R) C/C++ 优化编译器 19.29.30040 版
版权所有(C) Microsoft Corporation。保留所有权利。
dll_declsec_client_LoadErrorFunc.cpp
dll_declsec_client_LoadErrorFunc.cpp(1): warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
Microsoft (R) Incremental Linker Version 14.29.30040.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:dll_declsec_client_LoadErrorFunc.exe
dll_declsec_client_LoadErrorFunc.obj
D:\Cpath\studyDir\dllWorld\V3>cl /EHsc dll_declsec_client_LoadRightFunc.cpp
用于 x64 的 Microsoft (R) C/C++ 优化编译器 19.29.30040 版
版权所有(C) Microsoft Corporation。保留所有权利。
dll_declsec_client_LoadRightFunc.cpp
dll_declsec_client_LoadRightFunc.cpp(1): warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
Microsoft (R) Incremental Linker Version 14.29.30040.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:dll_declsec_client_LoadRightFunc.exe
dll_declsec_client_LoadRightFunc.obj
D:\Cpath\studyDir\dllWorld\V3>dll_declsec_client_LoadRightFunc.exe
dllMain func锛歭oaded in memory!
dll loaded!
FuncInDll is called!
D:\Cpath\studyDir\dllWorld\V3>dll_declsec_client_LoadErrorFunc.exe
::LoadLibrary("dll_declsec.dll")====> return null
not found FuncInDll function
9的code
//dll_declsec.cpp
#include <objbase.h>
#include <iostream>
using namespace std;
extern "C" __declspec(dllexport) void FuncInDll(void){
cout<<"FuncInDll is called!"<<endl;
}
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, void* lpReserved){
HANDLE g_hModule;
switch(dwReason){
case DLL_PROCESS_ATTACH:
cout<<"dllMain func:loaded in memory!"<<endl;
g_hModule = (HINSTANCE)hModule;
break;
case DLL_PROCESS_DETACH:
g_hModule=NULL;
break;
}
return TRUE;
}
//dll_declsec_client_LoadErrorFunc.cpp
#include <windows.h>
#include <iostream>
using namespace std;
int main(void){
//定义一个函数指针
typedef void (* DLLWITHLIB )(void);
//定义一个函数指针变量
DLLWITHLIB pfFuncInDll = NULL;
//加载我们的dll
HINSTANCE hinst=::LoadLibrary("dll_declsec2.dll");
if (NULL != hinst){
cout<<"dll loaded!"<<endl;
}else{
cout<<"::LoadLibrary(\"dll_declsec.dll\")====> return null"<<endl;
}
//找到dll的FuncInDll函数
pfFuncInDll = (DLLWITHLIB)GetProcAddress(hinst, "FuncInDll");
//调用dll里的函数
if (NULL != pfFuncInDll)
{
(*pfFuncInDll)();
}else{
cout<<"not found FuncInDll function"<<endl;
}
return 0;
}
//dll_declsec_client_LoadRightFunc.cpp
#include <windows.h>
#include <iostream>
using namespace std;
int main(void){
//定义一个函数指针
typedef void (* DLLWITHLIB )(void);
//定义一个函数指针变量
DLLWITHLIB pfFuncInDll = NULL;
//加载我们的dll
HINSTANCE hinst=::LoadLibrary("dll_declsec.dll");
if (NULL != hinst){
cout<<"dll loaded!"<<endl;
}else{
cout<<"::LoadLibrary(\"dll_declsec.dll\")====> return null"<<endl;
}
//找到dll的FuncInDll函数
pfFuncInDll = (DLLWITHLIB)GetProcAddress(hinst, "FuncInDll");
//调用dll里的函数
if (NULL != pfFuncInDll)
{
(*pfFuncInDll)();
}else{
cout<<"not found FuncInDll function"<<endl;
}
return 0;
}