1

テキスト ファイルからデータを読み取り、それを 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
4

1 に答える 1

1

Data.Word から数値を Word32 として定義するだけです。

number :: Word32
number = 42

また、次のような通常の値で sizeOf を使用することもできます: sizeOf number

于 2013-11-10T18:33:31.777 に答える