2009-11-15 69 views
4

我有一個C函數,它創建一個以空字符結尾的字符串並返回一個指向它的指針,還有相應的釋放函數。peekCString和peekCStringLen是否懶惰?

foreign import ccall unsafe "get_str" getStr :: IO CString 
foreign import ccall unsafe "free_str" freeStr :: CString -> IO() 

我想盡快從返回的CString的,和免費的CString創建一個Haskell字符串。

do cStr <- getStr 
    str <- peekCString cStr 
    freeStr cStr 
    -- here str is used 

使用str之前釋放cStr是否安全?換句話說,peekCString是一次創建Haskell String還是懶惰地創建?

回答

7

peekCString是嚴格的 - 例如,它不會通過unsafeInterleaveIO掛起循環,所以一旦您擁有了字符串頭部,您就已經計算出了尾部。下面是執行:

peekCAString cp = do 
    l <- lengthArray0 nUL cp 
    if l <= 0 then return "" else loop "" (l-1) 
    where 
    loop s i = do 
     xval <- peekElemOff cp i 
     let val = castCCharToChar xval 
     val `seq` if i <= 0 then return (val:s) else loop (val:s) (i-1) 
+0

如果我有一個C函數,沒有副作用和返回一個字符串,我可以欺騙哈斯克爾以爲'getStr >> = peekCString'不是'IO String',而是'String'?它在http://hackage.haskell.org/package/base-4.7.0.2/docs/src/Foreign-C-String.html#peekCString中聲明爲'peekCString :: CString - > IO String' –