Haskell FFI: FunPtr верхнего уровня для функции верхнего уровня? - PullRequest
2 голосов
/ 20 июня 2011

Желательно создать FunPtr для функции верхнего уровня только один раз, вместо того, чтобы создавать новую (для той же функции) всякий раз, когда это необходимо, и иметь дело с ее освобождением.

Я пропускаю какой-тополучить FunPtr, отличный от foreign import ccall "wrapper"?Если нет, мой обходной путь будет таким, как в приведенном ниже коде.Это безопасно?

type SomeCallback = CInt -> IO ()

foreign import ccall "wrapper" mkSomeCallback :: SomeCallback -> IO (FunPtr SomeCallback)

f :: SomeCallback
f i = putStrLn ("It is: "++show i)

{-# NOINLINE f_FunPtr #-}
f_FunPtr :: FunPtr SomeCallback
f_FunPtr = unsafePerformIO (mkSomeCallback f)

Редактировать: Проверено, что вариант "создание нового каждый раз" (main = forever (mkSomeCallback f)) действительно приводит к утечке памяти, если не freeHaskellFunPtr это.

1 Ответ

4 голосов
/ 20 июня 2011

Это, в принципе, должно быть безопасно - внутренний код GHC использует аналогичный шаблон для инициализации одиночных кодов, таких как очереди IO-отслеживаемых дескрипторов. Просто помните, что у вас нет контроля над запуском mkSomeCallback, и не забудьте NOINLINE.

...