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 个字节,其他两个字节被垃圾占用。我怎样才能防止这种情况?任何帮助将不胜感激。我对 Haskell 很陌生(最近才完成 LYAH),所以请放轻松。:)

另外,我真的很想知道更有经验的 Haskellers 使用哪些库来与 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 回答