3

似乎希望只为顶级函数创建一次 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话。

4

1 回答 1

5

原则上,这应该是安全的 - GHC 内部代码使用类似的模式来初始化单例,例如 IO 监视处理队列。请记住,您无法控制 mkSomeCallback 何时运行,并且不要忘记NOINLINE.

于 2011-06-20T05:37:58.390 回答