Являются ли peekCString и peekCStringLen ленивыми?
-
20-09-2019 - |
Вопрос
У меня есть функция 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 всю сразу или она создается лениво?
Решение
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)
Не связан с StackOverflow