gpt4 book ai didi

haskell - 如何捕获在 C 函数调用的 Haskell 回调函数中引发的 Haskell 异常?

转载 作者:行者123 更新时间:2023-12-04 01:11:18 26 4
gpt4 key购买 nike

有没有什么好的方法可以捕获在 c 函数调用的 haskell 回调函数中抛出的 haskell 异常?

例如,让我有一个简单的 c 函数,它只调用给定的回调,

void callmeback ( void (*callback) () ) {
callback ();
}

以及通过 ffi 使用此功能的 haskell 代码。
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE ForeignFunctionInterface #-}
module Main (main) where

import Foreign
import Control.Exception
import Data.Typeable

foreign import ccall safe "wrapper"
mkCallback :: IO () -> IO (FunPtr (IO ()))

foreign import ccall safe "callmeback"
callmeback :: FunPtr (IO ()) -> IO ()

data AnError = AnError String deriving (Show, Eq, Typeable)
instance Exception AnError

callback :: IO ()
callback = throwIO $ AnError "Catch me."

callMeBack :: IO () -> IO ()
callMeBack f = do fp <- mkCallback f
callmeback fp
main = do callMeBack callback `catch`
(\ e -> do putStrLn $ show (e :: AnError)
putStrLn "I caught you." )
putStrLn "-- Happy end."

执行结果(使用GHC 7.8.2编译)如下:
% ./Catch
Catch: AnError "Catch me."

所以看起来像是 callback 中抛出的异常抓不到 main .
我怎样才能使这种代码运行良好?

最佳答案

您必须手动执行此操作,如下所示:

  • 将回调函数包装在调用 try 的 Haskell 代码中, 然后序列化得到的 Either SomeException ()转换为可以从 C 处理的格式(您可以使用 StablePtr 来表示 SomeException,但关键是您需要以某种方式处理 Either)。
  • 在 C 代码调用回调的地方,检查结果是否为 Left exn如果是这样,请将错误传播到 C 代码的顶层,并在此过程中适本地释放资源。这一步是非机械的,因为 C 没有异常。
  • 在 C 代码的顶层,重新序列化异常或结果,并在 Haskell 函数中读取它,该函数将您对 C 代码的调用包装起来,引发异常或根据需要返回结果。

  • 我不知道任何执行此操作的程序示例。

    关于haskell - 如何捕获在 C 函数调用的 Haskell 回调函数中引发的 Haskell 异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29727644/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com