两者有什么区别?
即用于查找函数,例如 Nt___ 或 Zw___
在 MS Windos 中,隐式链接和显式链接是有区别的。
隐式链接
可执行文件与.lib
提供从 DLL 导出的符号的随附库(文件)链接。(用于导入的函数用 标记__declspec(dllimport)
。)隐式链接的 DLL 加载有可执行文件。
显式链接
该程序加载一个显式调用LoadLibrary()
. 要调用 DLL 的函数,它们的地址必须使用GetProcAddress()
.
但是,GetProcAddress()
也可以用于来自隐式链接 DLL 的函数。如果意外地在多个 DLL 中使用了相同的符号(例如,如果使用了链接到不同运行时 DLL 的 DLL),这将很有帮助。
有时,提供的 DLL 没有导入库。一个众所周知的例子是 OpenGL,MS 在 1.2 版中停止了对它的支持。但是,如果有足够的硬件和最新的驱动程序,当前 OpenGL 版本的所有功能都可能可用(并且可以GetProcAdress()
在运行时加载)。
一段用于 OpenGL 绑定的示例代码MyGL.cc
:
// version 2.0
glAttachShader
= (PFNGLATTACHSHADERPROC)wglGetProcAddress(
"glAttachShader");
glCompileShader
= (PFNGLCOMPILESHADERPROC)wglGetProcAddress(
"glCompileShader");
glCreateProgram
= (PFNGLCREATEPROGRAMPROC)wglGetProcAddress(
"glCreateProgram");
glCreateShader
= (PFNGLCREATESHADERPROC)wglGetProcAddress(
"glCreateShader");
glDeleteProgram
= (PFNGLDELETEPROGRAMPROC)wglGetProcAddress(
"glDeleteProgram");
glDeleteShader
= (PFNGLDELETESHADERPROC)wglGetProcAddress(
"glDeleteShader");
与MyGL.h
:
// Version 2.0
extern MY_GL_API PFNGLATTACHSHADERPROC glAttachShader;
extern MY_GL_API PFNGLCOMPILESHADERPROC glCompileShader;
extern MY_GL_API PFNGLCREATEPROGRAMPROC glCreateProgram;
extern MY_GL_API PFNGLCREATESHADERPROC glCreateShader;
extern MY_GL_API PFNGLDELETEPROGRAMPROC glDeleteProgram;
extern MY_GL_API PFNGLDELETESHADERPROC glDeleteShader;
whereMY_GL_API
定义为何__declspec(dllexport)
时MyGL.dll
编译,__declspec(dllimport)
否则。(所以,实际上__declspec(dllimport)
而 GetProcAddress()
不是vs. as 函数指针本身是dllexport
ed 但在运行时初始化 unsing GetProcAddress()
。)
(PFNGL
宏扩展为具有适当签名的函数指针类型。它们包含在kronos.org提供的标头中。)
的另一个重要用途GetProcAddress()
是在某个版本的 Windows 之前可能不存在的函数(或其他可能在 DLL 中可用或不可用的函数)。GetProcAddress()
因此,可以向后兼容编写应用程序,从而在预期功能失败时提供替代的回退。
MSDN 上提供的示例GetProcAddress()
:
typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);
// Call GetNativeSystemInfo if supported or GetSystemInfo otherwise.
PGNSI pGNSI;
SYSTEM_INFO si;
ZeroMemory(&si, sizeof(SYSTEM_INFO));
pGNSI = (PGNSI) GetProcAddress(
GetModuleHandle(TEXT("kernel32.dll")),
"GetNativeSystemInfo");
if (NULL != pGNSI) {
pGNSI(&si);
} else {
GetSystemInfo(&si);
}
进一步阅读:MSDN:将可执行文件链接到 DLL
GetProcAddress()
让您在运行时查找函数。它对于可选导入或可以动态加载的插件之类的东西很有用。它的另一个用途是用于导出但没有头文件或库文件的未记录函数。
Using__declspec( dllimport )
将该函数添加到您的导入表中,以便它与您的可执行文件一起自动加载。