似乎只需要为顶级函数创建一个FunPtr,而不是在需要时创建一个新函数(到同一个函数)并处理它的释放。
我是否忽略了获取除foreign import ccall "wrapper"
以外的FunPtr的某种方式?如果没有,我的解决方法将如下面的代码中所示。这样安全吗?
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
它。
答案 0 :(得分:4)
原则上,这应该是安全的 - GHC内部代码使用类似的模式初始化单例,例如IO监视句柄队列。请记住,您无法控制mkSomeCallback何时运行,并且不要忘记NOINLINE
。