テキスト ファイルからデータを読み取り、それを Windows レジストリにインポートする小さなプログラムを作成したいと考えています。System.Win32.Registry パッケージで Windows 関数へのバインドを見つけましたが、regSetValueEx関数で問題が発生しました。数値を DWORD (Word32) としてインポートしたい場合、それを regSetValueEx に渡して目的の結果を得る方法がわかりません。
現在、数値を TCHAR として保存し、 alloca と poke を使用してポインターを取得しています。テストに使用しているコードは次のとおりです。
module Main where
import Foreign.Marshal.Alloc
import Foreign.Storable
import System.Win32.Registry
import System.Win32.Types
number :: TCHAR
number = 42
getKey :: IO HKEY
getKey = regOpenKey hKEY_CURRENT_USER "test"
importFromTCHAR :: IO ()
importFromTCHAR = alloca $ \ptr -> do
poke ptr number
key <- getKey
regSetValueEx key "tchar" rEG_DWORD ptr (sizeOf (undefined::DWORD))
main :: IO ()
main = importFromTCHAR
結果: 0x0184002a
ちょっとうまくいきますが、TCHAR 値のサイズは 2 バイトしかないため、残りの 2 バイトはジャンクに取り込まれます。どうすればこれを防ぐことができますか? どんな助けでも大歓迎です。私は Haskell の初心者です (最近 LYAH を完成させたばかりです)。:)
また、経験豊富な Haskeller が Windows レジストリとのインターフェイスに使用しているライブラリを知りたいです。作業を容易にするライブラリはありますか?
編集: わかりました。Hackage でパッケージを調べているときに判明したように、Foreign.Ptr パッケージの castPtr 関数を見逃していました。それを使えば解決策は本当に簡単なので、私はばかのように感じます。Ilyaの回答によると、番号をWord32(またはDWORD)として保存し、allocaが提供するポインタにそれを挿入し、regSetValueExに渡す前にcastPtrを呼び出すだけです。変更されたコードは次のとおりです。
module Main where
import Foreign.Marshal.Alloc
import Foreign.Ptr
import Foreign.Storable
import System.Win32.Registry
import System.Win32.Types
number :: DWORD
number = 42
getKey :: IO HKEY
getKey = regOpenKey hKEY_CURRENT_USER "test"
importFromDWORD :: IO ()
importFromDWORD = alloca $ \ptr -> do
poke ptr number
key <- getKey
regSetValueEx key "dword" rEG_DWORD (castPtr ptr) (sizeOf number)
main :: IO ()
main = importFromDWORD