DLL那些事(3)
链接和导入库 (Linking and Import Libraries)
显式链接(Explicit Linking)
// PrintGreeting.cpp
#include <Windows.h>
#include <stdio.h>
int main()
{
HMODULE const HelloDll = LoadLibraryExW(L"Hello.dll", nullptr, 0);
// char const* __cdecl GetGreeting();
using GetGreetingType = char const* (*__cdecl)();
GetGreetingType const GetGreeting =
reinterpret_cast<GetGreetingType>(
GetProcAddress(HelloDll, "GetGreeting"));
puts(GetGreeting());
return 0;
}
编译:
将源码和hello.dll放到同一个目录下 输入cl PrintGreeting.cpp
即可得到PrintGreeting.exe
在命令行运行编译好的程序可以看到一下输出
使用dumpbin.exe 查看PrintGreeting.exe依赖的DLL
可以看到PrintGreeting.exe依赖的动态库只有kernel32.dll,没有hello.dll
再使用dumpbin.exe查看一下PrintGreeting.exe的导入表,输入dumpbin.exe /imports PrintGreeting.exe
会列出很长的一堆东西,我们这里只展示一部分。
可以看到程序是通过kernel32.dll中的函数加载调用DLL的,所以我们不能动态加载和调用kernel32.dll中的函数。
隐式链接(Implicit Linking)
// PrintGreetingImplicit.cpp
#include <stdio.h>
extern "C" char const* GetGreeting();
int main(){
puts(GetGreeting());
return 0;
}
编译
与显示链接不同,隐式链接的编译过程相对复杂一点
link Hello.obj /DLL /NOENTRY /EXPORT:GetGreeting
cl /c PringGreetingImplicit.cpp
link PringGreetingImplicit.obj Hello.lib
可以看到隐式链接编译出来的程序是直接依赖hello.dll动态库的。