GetProcAddress与__declspec(dllimport) [英] GetProcAddress vs __declspec( dllimport )

查看:217
本文介绍了GetProcAddress与__declspec(dllimport)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

两者之间有什么区别?

即用于查找诸如Nt___或Zw ___

i.e. for finding functions such as Nt___ or Zw___

推荐答案

在MS Windos中,隐式链接有区别>和显式链接

In MS Windos, there is a difference between implicit linking and explicit linking.

隐式链接

可执行文件针对随附库( .lib 文件),该库提供从DLL导出的符号。 (用于导入的功能用 __ declspec(dllimport)标记。)隐式链接的DLL加载了可执行文件。

The executable is linked against the accompanying library (.lib file) which provides the symbols exported from DLL. (The functions for import are remarked with __declspec(dllimport).) Implicit linked DLLs are loaded with executable.

显式链接

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

The program loads a DLL explicitly calling LoadLibrary(). To call functions of the DLL their address has to be determined using GetProcAddress().

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

However, GetProcAddress() can be used as well for functions which come from implicit linked DLLs. This can be helpful, if accidentally the same symbol is available in multiple DLLs (e.g. if DLLs have been used which are linked against different runtime DLLs).

有时,DLL是没有提供导入库。一个著名的例子是OpenGL,MS停止了对该版本的支持。但是,如果有足够的硬件和最新的驱动程序,则可能会使用当前OpenGL版本的所有功能(并且可以在运行时用 GetProcAdress()加载-时间)。

Sometimes, DLLs are provided without import libraries. A wellknown example is OpenGL for which MS stopped support with version 1.2. However, with sufficient H/W and up-to-date drivers, all functions of the current OpenGL version might be availabe (and can be loaded with GetProcAdress() at run-time).

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

A piece of sample code for OpenGL binding 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 定义为<$ c编译 MyGL.dll __ declspec(dllimport) __ declspec(dllexport) >否则。 (因此,实际上是 __ declspec(dllimport) GetProcAddress()而不是 vs。,因为函数指针本身是 dllexport ,但是在运行时初始化时不使用 GetProcAddress()。 )

where MY_GL_API is defined as __declspec(dllexport) when MyGL.dll is compiled and __declspec(dllimport) otherwise. (So, actually __declspec(dllimport) and GetProcAddress() instead of vs. as function pointers themselves are dllexported but initialized at run-time unsing GetProcAddress().)

PFNGL 宏扩展为具有适当签名的函数指针类型。它们包含在提供的标题中通过 kronos.org 。)

(The PFNGL macros expand to function pointer types with the appropriate signature. They are included from a header provided by kronos.org.)

GetProcAddress()的另一个重要用法是用于某些特定版本的Windows之前可能不存在的功能(或其他功能可能在Windows中不可用) DLL)。因此,应用程序可以向后兼容,当 GetProcAddress()失败时提供备用功能。

Another important usage of GetProcAddress() is for functions which may exist not before a certain version of Windows (or other functions which may or may not be available in DLLs). Thus, the application can be written backwards compatible providing an alternative fall-back when GetProcAddress() fails for the intended function.

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

The sample provided on MSDN for 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与__declspec(dllimport)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆