PeekCString и peekCStringLen ленивы? - PullRequest
4 голосов
/ 16 ноября 2009

У меня есть функция C, которая создает строку с нулевым символом в конце и возвращает указатель на нее, также есть соответствующая функция освобождения.

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

Я хочу создать строку Haskell из возвращенной CString и освободить CString как можно скорее.

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

Безопасно ли освобождать cStr перед использованием str? Другими словами, peekCString создает строку Haskell сразу или она создается лениво?

1 Ответ

7 голосов
/ 16 ноября 2009

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)
...