4

我有一个 C 函数,它创建一个以空结尾的字符串并返回一个指向它的指针,还有相应的释放函数。

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

我想从返回的 CString 中创建一个 Haskell 字符串,并尽快释放 CString。

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

在使用 str 之前释放 cStr 是否安全?换句话说,peekCString 是一次性创建 Haskell String,还是懒惰地创建?

4

1 回答 1

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)
于 2009-11-15T23:46:14.130 回答