GetProcAddress

显式链接到 DLL 的进程会调用 GetProcAddress,以获取 DLL 中导出函数的地址。 可使用返回的函数指针调用 DLL 函数。 GetProcAddress 采用 DLL 模块句柄(由 LoadLibraryAfxLoadLibrary 或 GetModuleHandle 返回)作为参数,并采用要调用的函数的名称或函数的导出序号。

因为通过指针调用 DLL 函数,并且没有编译时类型检查,所以请确保函数的参数正确,以便不会超过在堆栈上分配的内存以及导致访问冲突。 帮助提供类型安全的一种方法是查看导出函数的函数原型,并为函数指针创建匹配的 typedef。 例如:

typedef UINT (CALLBACK* LPFNDLLFUNC1)(DWORD,UINT);
...

HINSTANCE hDLL;               // Handle to DLL
LPFNDLLFUNC1 lpfnDllFunc1;    // Function pointer
DWORD dwParam1;
UINT  uParam2, uReturnVal;

hDLL = LoadLibrary("MyDLL");
if (hDLL != NULL)
{
   lpfnDllFunc1 = (LPFNDLLFUNC1)GetProcAddress(hDLL,
                                           "DLLFunc1");
   if (!lpfnDllFunc1)
   {
      // handle the error
      FreeLibrary(hDLL);
      return SOME_ERROR_CODE;
   }
   else
   {
      // call the function
      uReturnVal = lpfnDllFunc1(dwParam1, uParam2);
   }
}

如何指定调用 GetProcAddress 时所需的函数取决于 DLL 的生成方式。

仅当要链接到的 DLL 使用模块定义 (.def) 文件生成,并且序号随函数在 DLL .def 文件的 EXPORTS 节中列出时,才能获取导出序号。 如果 DLL 具有许多导出函数,则与使用函数名称相比,使用导出序号调用 GetProcAddress 会稍微快一些,因为导出序号充当 DLL 导出表中的索引。 使用导出序号,GetProcAddress 可以直接查找函数,而不是将指定名称与 DLL 导出表中的函数名进行比较。 但是,仅当可控制将序号分配给 .def 文件中的导出函数时,才应使用导出序号调用 GetProcAddress

你希望做什么?

你想进一步了解什么?

另请参阅

在 Visual Studio 中创建 C/C++ DLL