我正在尝试为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") ;
答案 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
有一个字符串参数,您需要添加A
或W
,具体取决于您是否要传递ANSI或Unicode字符串,即需要使用{{ 1}}或RegDeleteKeyExA
。
此外,根据调用约定,第三方DLL中的函数名称通常以各种方式修饰。 (但是,Windows系统DLL不使用名称修饰,因此您不需要在此处考虑这一点。)同样,Old New Thing有一个good explanation。
您可以使用Visual C ++附带的dumpbin
程序列出DLL的所有导出(它将显示您需要传递给RegDeleteKeyExW
的实际函数名称):
GetProcAddress