GetProcAddress为RegDeleteKeyEx返回NULL

时间:2012-10-10 06:59:33

标签: windows winapi registry

我正在尝试为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") ;

2 个答案:

答案 0 :(得分:4)

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)。

答案 1 :(得分:1)

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

由于RegDeleteKeyEx有一个字符串参数,您需要添加AW,具体取决于您是否要传递ANSI或Unicode字符串,即需要使用{{ 1}}或RegDeleteKeyExA

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

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

GetProcAddress
相关问题