2011-06-20 74 views
2

只需一次就創建一個頂級函數而不是創建一個新的函數(對同一個函數),並且處理它的釋放處理似乎是可取的。Haskell FFI:頂級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它。

回答

4

原則上這應該是安全的--GHC內部代碼使用類似的模式來初始化單例,如IO監視句柄隊列。請記住,您無法控制mkSomeCallback何時運行,並且不會忘記NOINLINE