2009-11-15 43 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' –