2

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

问题:: 即使在 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") ;
4

2 回答 2

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定义)使用适当的符号名称。

于 2012-10-10T07:15:06.020 回答
1

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

由于RegDeleteKeyEx有一个字符串参数,您需要添加AorW取决于您是否要传递 ANSI 或 Unicode 字符串,即您需要使用RegDeleteKeyExAor RegDeleteKeyExW

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

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

dumpbin /exports mydll.dll
于 2012-10-10T07:09:35.927 回答