0

两者有什么区别?

即用于查找函数,例如 Nt___ 或 Zw___

4

2 回答 2

1

在 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 函数指针本身是dllexported 但在运行时初始化 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

于 2018-09-15T05:10:21.237 回答
0

GetProcAddress()让您在运行时查找函数。它对于可选导入或可以动态加载的插件之类的东西很有用。它的另一个用途是用于导出但没有头文件或库文件的未记录函数。

Using__declspec( dllimport )将该函数添加到您的导入表中,以便它与您的可执行文件一起自动加载。

于 2018-09-15T05:07:30.170 回答