tmi*_*zmd 12 haskell exception ffi
有没有什么好方法可以捕获haskell异常,它被ac函数调用的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.如何才能使这种代码运行良好?
您必须手动执行此操作,如下所示:
将您的回调函数包装在调用 的 Haskell 代码中try,然后将结果序列化为Either SomeException ()您可以从 C 处理的格式(您可以将 a 用于StablePtr,SomeException但要点是您需要以Either某种方式处理)。
在 C 代码调用回调的地方,检查结果是否为 a Left exn,如果是,则将错误传播到 C 代码的顶层,并在此过程中适当释放资源。此步骤是非机械的,因为 C 没有例外。
在 C 代码的顶层,重新序列化异常或结果,并在 Haskell 函数中读取它,该函数包装对 C 代码的调用,引发异常或返回适当的结果。
我不知道有任何程序可以执行此操作。
| 归档时间: | 
 | 
| 查看次数: | 302 次 | 
| 最近记录: |