c – GetProcAddress与__declspec(dllimport)
作者:互联网
这两者有什么区别?
即用于查找Nt___或Zw___等功能
解决方法:
在MS Windos中,隐式链接和显式链接之间存在差异.
隐式链接
可执行文件链接到附带的库(.lib文件),该库提供从DLL导出的符号. (导入的函数用__declspec(dllimport)标记.)隐式链接的DLL加载了可执行文件.
显式链接
该程序加载一个显式调用LoadLibrary()的DLL.要调用DLL的函数,必须使用GetProcAddress()确定其地址.
但是,GetProcAddress()
也可以用于来自隐式链接DLL的函数.如果在多个DLL中偶尔出现相同的符号(例如,如果已经使用了针对不同运行时DLL链接的DLL),这可能会有所帮助.
有时,DLL没有导入库.一个众所周知的例子是OpenGL,MS停止支持版本1.2.但是,如果有足够的H / W和最新驱动程序,当前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;
其中MY_GL_API在编译MyGL.dll时定义为__declspec(dllexport),否则定义为__declspec(dllimport). (所以,实际上__declspec(dllimport)和GetProcAddress()而不是vs作为函数指针本身是dllexported但在运行时未初始化的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: Link an executable to a DLL
标签:c,windows,winapi,ntdll 来源: https://codeday.me/bug/20191003/1850169.html