我应该使用 GetProcAddress 还是只包含各种 win32 库?

Posted

技术标签:

【中文标题】我应该使用 GetProcAddress 还是只包含各种 win32 库?【英文标题】:Should I use GetProcAddress or just include various win32 libraries? 【发布时间】:2009-01-29 21:12:35 【问题描述】:

想知道两者有什么区别:

static PROCESSWALK pProcess32First=(PROCESSWALK)GetProcAddress(hKernel,"Process32First");
...
pProcess32First(...);

什么是hKernel?查看here。你可以替换成GetModuleHandle()

#include <Tlhelp32.h>
...
Process32First(...);

有什么区别,我想知道我应该使用哪个。那么在最佳实践方面有什么不同吗?

【问题讨论】:

【参考方案1】:

注意:我的回答假设该功能在任何一种方式下都可用,如果您使用非导出功能,还有其他事情需要考虑。

如果您使用 LoadLibrary 和 GetProcAddress,那么如果所需的库不存在,您可以选择以减少的功能运行。如果您使用包含并直接链接 lib,而 dll 不存在(或由于版本错误而没有导出),您的应用将无法加载。

如果你想使用一个不在给定 dll 的所有版本中的函数,它真的会有所不同。

【讨论】:

【参考方案2】:

除了 Evan 所说的(这是正确的)之外,另一个重要的区别(恕我直言)是,如果您要动态加载函数,则需要有一个 typedef 将 void* 转换为才能调用该函数一次它已加载。除非定义静态链接的函数原型的头文件具有一种机制,可以从相同的模板函数定义代码中定义函数指针的 typedef,否则您最终会得到一个重复的函数定义,可能在您的代码中。如果外部头文件定义被更新(例如,使用 64 位数据类型的新定义),除非您更新其他函数原型(这些不会在编译时被捕获,因为 c-样式转换为函数 typedef)。

这是一个微妙的问题,但却是一个需要考虑的重要问题。由于这个问题,如果可以的话,我会使用隐式(“静态”)链接,如果你正在使用动态加载,请注意这个问题,并尽可能地构建你的代码以避免将来出现问题。

【讨论】:

【参考方案3】:

微软的解释见here。

隐式链接(使用*.lib)更简单。

至于内核库,没有其他区别。

【讨论】:

【参考方案4】:

如果我有用户可能有也可能没有的可选插件库,我会采用第一种方法。对于必要的库,我会使用第二个,因为获取函数的代码要少得多。

【讨论】:

以上是关于我应该使用 GetProcAddress 还是只包含各种 win32 库?的主要内容,如果未能解决你的问题,请参考以下文章

GetProcAddress() 为 .NET DLL 返回 Nil

即使使用 LoadLibrary 和 GetProcAddress,ChoosePixelFormat 也会崩溃

有没有办法找到要在 GetProcAddress 中使用的 C++ 错位名称?

为啥 GetProcAddress() 不起作用?

GetProcAddress 使用注意事项

为啥传统的 GetProcAddress 到 std::function 工作不简单