2

32ビットと64ビットの両方のOSでレジストリキーの再帰的な削除を実装しようとしています。XP x64 Professional未満のOSでは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は、文字列を受け入れるか返す関数の2つのバージョンをエクスポートします。1つはANSI文字列を受け取り、もう1つはUnicode文字列を受け取ります。ANSIバージョンにAは関数の名前が追加されており、UnicodeバージョンにはW(「ワイド」文字列用)があります。Old New Thingには、これをより詳細に説明する記事があります。

には文字列引数があるため、ANSIまたはUnicode文字列を渡すかどうかに応じて、またはRegDeleteKeyExを追加する必要があります。つまり、またはを使用する必要があります。AWRegDeleteKeyExARegDeleteKeyExW

さらに、サードパーティのDLLの関数の名前は、呼び出し規約に従ってさまざまな方法で装飾されることがよくあります。(ただし、WindowsシステムDLLは名前の装飾を使用しないため、ここでこれを考慮する必要はありません。)繰り返しになりますが、OldNewThingには適切な説明があります。

Visual C ++に含まれているプログラムGetProcAddressを使用して、DLLのすべてのエクスポート(渡す必要のある実際の関数名が表示されます)を一覧表示できます。dumpbin

dumpbin /exports mydll.dll
于 2012-10-10T07:09:35.927 に答える