【问题标题】:GetProcAddress returning NULL for RegDeleteKeyExGetProcAddress 为 RegDeleteKeyEx 返回 NULL
【发布时间】:2012-10-10 06:59:32
【问题描述】:

我正在尝试为 32 位和 64 位操作系统实现注册表项的递归删除。由于 RegDeleteKeyEx 没有为低于 XP x64 Professional 的操作系统定义,我正在尝试间接使用该功能。

问题:: 即使在 x64 上,GetProcAddress() 也会返回 NULL。

//Global Declarations 
typedef LONG (WINAPI * PFN_RegDeleteKeyEx)(HKEY hKey , LPCTSTR lpSubKey , REGSAM samDesired , DWORD Reserved );
PFN_RegDeleteKeyEx _RegDeleteKeyEx ;

//The code inside function
hAdvAPI32 = LoadLibrary(TEXT("Advapi32.dll"));
_RegDeleteKeyEx = (PFN_RegDeleteKeyEx)GetProcAddress( hAdvAPI32, "RegDeleteKeyEx" );
if( _RegDeleteKeyEx == NULL )
     printf("NULL\n") ;

【问题讨论】:

  • 改用“RegDeleteKeyExW”。
  • @HansPassant:如果他的代码在没有 UNICODE 的情况下编译,硬编码宽字符变体将是错误的,因为他在他的 typedef 中使用了 LPC*T*STR
  • @HansPassant- 感谢伙伴的帮助。我明白了这个概念:-)

标签: windows winapi registry


【解决方案1】:

RegDeleteKeyEx 实际上并不是一个函数——它是一个宏。根据您是否定义了UNICODE,宏会扩展为 MSDN 页面底部给出的实际函数名称:

RegDeleteKeyExW (Unicode) and RegDeleteKeyExA (ANSI)

所以在你的情况下,你可能想要类似的东西

#ifdef UNICODE
    const char RegDeleteKeyExSymbol[] = "RegDeleteKeyExW";
#else 
    const char RegDeleteKeyExSymbol[] = "RegDeleteKeyExA";
#endif

_RegDeleteKeyEx = (PFN_RegDeleteKeyEx)GetProcAddress( hAdvAPI32, RegDeleteKeyExSymbol );

这将使用适当的符号名称,具体取决于您自己的代码的编译方式(定义或不定义 UNICODE)。

【讨论】:

  • 谢谢伙计...您的答案是最准确的,但马丁 B 已经说明了这一点。我的代码完美无缺。你的 ans 应该是被接受的,但你迟到了几分钟。
  • @user1696837:如果需要,您可以更改您接受的那个。
  • @user1696837 是的。你只需要检查这个其他答案。
【解决方案2】:

Windows 导出任何接受或返回字符串的函数的两个 版本:一种采用 ANSI 字符串,另一种采用 Unicode 字符串。 ANSI 版本有一个A 附加到函数的名称,而Unicode 版本有一个W(用于“宽”字符串)。 The Old New Thing 有 an article 更详细地解释了这一点。

由于RegDeleteKeyEx 有一个字符串参数,您需要添加AW,具体取决于您要传递ANSI 字符串还是Unicode 字符串,即您需要使用RegDeleteKeyExARegDeleteKeyExW

此外,第三方 DLL 中的函数名称通常根据调用约定以各种方式修饰。 (但是,Windows 系统 DLL 不使用名称修饰,因此您无需在此处考虑这一点。)同样,旧新事物有一个 good explanation

您可以使用 Visual C++ 中包含的 dumpbin 程序列出 DLL 的所有导出(它将显示您需要传递给 GetProcAddress 的实际函数名称):

dumpbin /exports mydll.dll

【讨论】:

  • 谢谢伙计……那些文章正是对问题的正确解释。
  • 事实上,Windows API 函数名是没有修饰的。如果是这种情况,那么它将类似于:_RegDeleteKeyExW@16。但事实并非如此。你真的应该从你的答案中删除那个误导性的文字。真正的答案是 Frerich 所说的。
  • @DavidHeffernan- 感谢您的披露。
  • @DavidHeffernan 感谢您指出这一点——我已经编辑了答案以纠正错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-29
  • 1970-01-01
  • 2014-08-07
  • 2021-07-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多