Рассмотрим следующий фрагмент кодаHaskell FFI: ForeignPtr кажется, чтобы не освободила
import qualified Foreign.Concurrent
import Foreign.Ptr (nullPtr)
main :: IO()
main = do
putStrLn "start"
a <- Foreign.Concurrent.newForeignPtr nullPtr $
putStrLn "a was deleted"
putStrLn "end"
Он производит следующий вывод (может быть ошибка GHC?):
start
end
я ожидал увидеть «a was deleted
» где-то после start
..
Я не знаю, что происходит. У меня есть несколько предположений:
- сборщик мусора не собирает оставшиеся объекты, когда программа завершает
putStrLn
перестает работать послеmain
отделки. (Кстати, я попробовал то же самое с foreignly импортируемогоputs
и получил те же результаты)- Моего понимание
ForeignPtr
так не хватает - GHC ошибки? (Окр: GHC 6.10.3, Intel Mac)
При использовании Foreign.ForeignPtr.newForeignPtr
вместо Foreign.Concurrent.newForeignPtr
, кажется, работает:
{-# LANGUAGE ForeignFunctionInterface #-}
import Foreign.C.String (CString, newCString)
import Foreign.ForeignPtr (newForeignPtr)
import Foreign.Ptr (FunPtr)
foreign import ccall "&puts" puts :: FunPtr (CString -> IO())
main :: IO()
main = do
putStrLn "start"
message <- newCString "a was \"deleted\""
a <- newForeignPtr puts message
putStrLn "end"
выходы:
start
end
a was "deleted"
Я могу воспроизвести это с помощью Foreign.Concurrent.newForeignPtr, но Foreign.ForeignPtr.newForeignPtr работает должным образом. Очень странно, так как они должны быть почти одинаковыми под капотом ... – ephemient
@ephemient: thanks. Я воспроизвел ваш результат и детали на мой вопрос. – yairchu
Я не могу воспроизвести это (GHC 6.10.3 на окнах). Версия Foreign.Concurrent.newForeignPtr работает для меня, и выходы start/end/a были удалены – jitter