首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GetProcAddress vs __declspec( dllimport )

GetProcAddress vs __declspec( dllimport )
EN

Stack Overflow用户
提问于 2018-09-15 04:56:23
回答 2查看 1.9K关注 0票数 0

这两者有什么区别?

即用于查找诸如Nt___或Zw___之类的函数

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-09-15 05:10:21

在MS中,隐式链接显式链接之间存在差异。

隐式连接

可执行文件链接到附带的库(.lib文件),该库提供从DLL导出的符号。(导入的函数是用__declspec(dllimport)表示的。)隐式链接DLL使用可执行文件加载。

显式链接

程序加载一个DLL显式调用LoadLibrary()。要调用DLL的函数,必须使用GetProcAddress()确定它们的地址。

但是,GetProcAddress()也可以用于来自隐式链接DLL的函数。如果在多个DLL中意外地使用了相同的符号(例如,如果使用了针对不同运行时DLL的DLL),则这可能会有所帮助。

有时,DLL是不带导入库的。一个著名的例子是OpenGL,MS停止了对其版本1.2的支持。但是,有了足够的H/W和最新的驱动程序,当前OpenGL版本的所有功能都可能可用(并且可以在运行时用GetProcAdress()加载)。

OpenGL绑定MyGL.cc的一段示例代码

代码语言:javascript
复制
  // 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

代码语言:javascript
复制
// 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)。(因此,实际上,__declspec(dllimport) GetProcAddress()而不是vs.as函数指针本身是dllexport编辑的,但在运行时取消GetProcAddress()时初始化。)

( PFNGL宏展开为具有适当签名的函数指针类型。它们是从kronos.org提供的头中包含的。)

GetProcAddress()的另一个重要用法是用于某些版本的Windows之前可能不存在的函数(或在DLL中可能可用或不可用的其他函数)。因此,当GetProcAddress()对预期函数失败时,可以向后编写兼容的应用程序,提供可选的回退。

在MSDN上为GetProcAddress()提供的示例

代码语言:javascript
复制
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

票数 1
EN

Stack Overflow用户

发布于 2018-09-15 05:07:30

GetProcAddress()允许您在运行时找到函数。对于可选的导入或可以动态加载的插件之类的东西,它非常有用。它的另一种用途是用于导出但没有头文件或库文件的无文档函数。

使用__declspec( dllimport )将函数添加到导入表中,这样它就会自动与您的可执行文件一起加载。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52341687

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档