GetProcAddress与__declspec(dllimport)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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
编译时,__declspec(dllexport)
被定义为MyGL.dll
,否则__declspec(dllimport)
。 (所以,实际上__declspec(dllimport)
和GetProcAddress()
而不是vs作为函数指针本身是dllexport
ed但在运行时未初始化的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
GetProcAddress()
允许您在运行时查找函数。它对于可选导入或可动态加载的插件等很有用。它的另一个用途是导出的未记录的函数,但没有头文件或库文件。
使用__declspec( dllimport )
将该函数添加到导入表中,以便随可执行文件自动加载。
以上是关于GetProcAddress与__declspec(dllimport)的主要内容,如果未能解决你的问题,请参考以下文章
__declspec(dllexport) 静态链接库到 dll
__declspec(dllexport) 和 __declspec(dllimport)的区别