Haskell FFI:顶级 FunPtr 到顶级函数?

发布于 2024-11-16 16:46:19 字数 602 浏览 3 评论 0原文

似乎最好只为顶级函数创建一次 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它的话。

It seems desirable to create a FunPtr to a top-level function just once instead of creating a new one (to the same function) whenever it's needed and dealing with its deallocation.

Am I overlooking some way to obtain the FunPtr other than foreign import ccall "wrapper"? If not, my workaround would be as in the code below. Is that safe?

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)

Edit: Verified that the "creating a new one every time" variant (main = forever (mkSomeCallback f)) does in fact leak memory if one doesn't freeHaskellFunPtr it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

兮子 2024-11-23 16:46:19

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

This should, in principle, be safe - GHC internal code uses a similar pattern to initialize singletons such as the IO watched-handles queues. Just keep in mind that you have no control over when mkSomeCallback runs, and don't forget the NOINLINE.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文