ページ 1 / 1
RegQueryValueEx()関数のエラー
Posted: 2007年3月06日(火) 15:32
by AxB
コード: 全て選択
Const DESKTOP_KEY = "Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
Const DESKTOP_KEY_VALUE = "Desktop"
Main()
Sub Main()
Dim hDesktopKey As HKEY
Dim pDesktopPath As VoidPtr
Dim DesktopPathLen As *DWord
RegOpenKeyEx(HKEY_CURRENT_USER, DESKTOP_KEY, 0, KEY_QUERY_VALUE, hDesktopKey)
RegQueryValueEx(hDesktopKey, DESKTOP_KEY_VALUE, 0, NULL, NULL, DesktopPathLen)
pDesktopPath = calloc(DesktopPathLen)
RegQueryValueEx(hDesktopKey, DESKTOP_KEY_VALUE, 0, NULL, pDesktopPath, DesktopPathLen)
RegCloseKey(hDesktopKey)
MessageBox(0, pDesktopPath, "", MB_OK)
free(pDesktopPath)
End Sub
上記コードの12行目と14行目のRegQueryValueEx()関数でエラーが出ます。
DesktopPathLen を VarPtr(DesktopPathLen) に書き換えるとエラーは出なくなりますが、
DesktopPathLenは *DWord型なのでVarPtr()関数は必要ないように思います。
何故こうしないとエラーになるのでしょうか。
Posted: 2007年3月06日(火) 15:37
by AxB
すみません、訂正です。
エラーになるのではなく、読み取ったデータのバイト数が正常にDesktopPathLenに格納されない、でした。
Posted: 2007年3月06日(火) 16:17
by のぶあや
コード: 全て選択
Dim DesktopPathLen As *DWord
というのはDWord型変数への
ポインタを格納する変数です。
これを宣言しただけでは
ポインタを格納する変数は確保されますが、
ポインタが指し示す
DWord型変数はまだ確保されていません。
なのでDWord型のサイズ分をメモリ確保する必要があります。
コード: 全て選択
Dim DesktopPathLen As *DWord
DesktopPathLen=calloc(SizeOf(DWord))
またRegQueryValueEx()関数にDesktopPathLenではなく
VarPtr(DesktopPathLen)を渡すとエラーがなくなるのは
ポインタ変数自体が
DWord型と同じ4Byteである(32bitCPUの場合)ので、
VarPtrで、ポインタを格納する変数への
ポインタを渡しているからです。
(ここでの「ポインタを格納する変数」とはDesktopPathLenのことです)
ごちゃごちゃとわかりにくいことを書きましたが、以下のようにすれば出来ます。
方法1
コード: 全て選択
Dim lpDesktopPathLen As *DWord 'ポインタ変数を宣言
lpDesktopPathLen=calloc(SizeOf(DWord)) 'メモリ確保
RegQueryValueEx(hDesktopKey, DESKTOP_KEY_VALUE, _
0, NULL, NULL, _
lpDesktopPathLen) '確保したメモリへのポインタを渡す
方法2
コード: 全て選択
Dim DesktopPathLen As DWord 'DWord型変数を宣言
RegQueryValueEx(hDesktopKey, DESKTOP_KEY_VALUE, _
0, NULL, NULL, _
VarPtr(DesktopPathLen)) '宣言したDWord型変数へのポインタを渡す
補足ですが、レジストリを扱うプログラムを組むときは
実行する前にレジストリのバックアップを取ることをオススメします
Posted: 2007年3月06日(火) 18:35
by AxB
わかりやすい解説ありがとうございます。
VarPtr(DesktopPathLen)で正常な動作になったのは、RegQueryValueEx()関数が
第6引数にとる変数とポインタ型変数とのサイズが一致したからなんですね。
疑問が晴れてすっきりしました。
>補足ですが、レジストリを扱うプログラムを組むときは
>実行する前にレジストリのバックアップを取ることをオススメします
助言ありがとうございます。そうしようと思います。