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

2023-12-26

有没有什么好方法来捕获由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。 我怎样才能使这种代码正常工作?


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

  • 将回调函数包装在调用的 Haskell 代码中try,然后序列化结果Either SomeException ()到您可以从 C 处理的格式(您可以使用StablePtr为了SomeException,但重点是你需要处理Either不知何故)。

  • 在您的 C 代码调用回调的地方,检查结果是否是Left exn如果是这样,则将错误传播到 C 代码的顶层,并在此过程中适当释放资源。此步骤是非机械的,因为 C 没有例外。

  • 在 C 代码的顶层,重新序列化异常或结果,并在 Haskell 函数中读取它,该函数包装对 C 代码的调用,引发异常或返回适当的结果。

我不知道有任何程序可以执行此操作。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何捕获 C 函数调用的 Haskell 回调函数中引发的 Haskell 异常? 的相关文章

  • 'lens' 的阴谋集团依赖性解析失败

    我刚刚做了一个阴谋更新并尝试从 hackage 安装 lens 这给了我以下错误 cabal install j lens Resolving dependencies Configuring dlist 0 7 0 1
  • 在析构函数中捕获异常

    是否可以让析构函数捕获异常然后重新抛出它们 如果是这样 我该怎么做 因为没有明确的地方try陈述 基本上 我想要理想地做 CMyObject CMyObject catch Catch without a try Possible LogS
  • CakePHP 2:新异常

    我想创建一个名为 SecurityException 的新异常 我应该把代码放在哪里 class SecurityException extends CakeException Thanks 创建一个 excepts php 文件 将其放在
  • 是否有一个基于对象身份的、线程安全的记忆库?

    我知道记忆化似乎是堆栈溢出的 haskell 标签上的一个长期话题 但我think以前没有人问过这个问题 我知道 Haskell 有几个不同的 现成 记忆库 memo combinators 和 memotrie 包 利用涉及惰性无限数据结
  • 如何找到仅是 2、3 和 5 的幂的倍数的所有数字的列表? [复制]

    这个问题在这里已经有答案了 I am trying to generate a list of all multiples which can be represented by the form where a b and c are w
  • GHC 是否使用存在类型的动态调度?

    下面的代码是否使用了 C 或 Java 中所理解的动态调度 据我了解 在最后一行 编译器不可能在编译时知道要调用哪个 实现 但代码会编译并产生正确的结果 有人可以解释一下 这背后有什么样的实现 例如 vptr 吗 LANGUAGE Exis
  • Haskell 测量函数性能

    在 Haskell 中 我如何 简单地 测量函数的性能 例如 运行需要多长时间 或者需要多少内存 我知道分析 但是 是否有一种更简单的方法不需要我对代码进行太多更改 测量运行需要多长时间以及需要多少内存是两个独立的问题 即 基准测试和分析
  • 反应性香蕉时间延迟

    我已经查阅了文档反应香蕉 http hackage haskell org package reactive banana 而且我找不到指定明确时间延迟的方法 举例来说 我想采取Event t a并将其所有发生的事件移至未来 1 秒 或获取
  • 在 Haskell 命令行应用程序中提示输入密码

    以下 Haskell 程序提示用户在终端中输入密码 如果输入正确则继续 main do putStrLn Password password lt getLine case hash password member database of
  • 服务具有零个应用程序(非基础设施)端点

    我最近创建了一个WCF服务 dll 和一个服务主机 exe 我知道我的 WCF 服务工作正常 因为我能够成功地将服务添加到 WcfTestClient 但是 当我从服务主机 exe 使用 WCF 时 我似乎遇到了问题 我可以将对 WCF d
  • 嵌套在其他 monad 中的 IO 操作未执行

    我有一个 foobar IO ParseResult String String ParseResult 是一个在这里定义的 monad https hackage haskell org package haskell src exts
  • 如何处理在组合下发生变化的类型?

    我最近读了一篇非常有趣的论文单调性类型 https infoscience epfl ch record 231867 files monotonicity types pdf其中描述了一种新的 HM 语言 该语言可以跟踪操作之间的单调性
  • 分层架构中的异常处理

    我们正在分层设计中重构 当然还有重新设计 我们的服务 我们有服务操作层 BLL 网络抽象层 gt 处理网络代理 数据抽象层 但我们对我们的异常处理策略有点困惑 我们不想向外界透露太多 BLL 的信息 从其他层到bll就可以了 我们不想让 t
  • Haskell 和 Idris 之间的区别:类型宇宙中运行时/编译时的反映

    因此 在 Idris 中 编写以下内容是完全有效的 item b Bool gt if b then Nat else List Nat item True 42 item False 1 2 3 cf https www youtube
  • 类型级编程有哪些示例? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我不明白 类型级编程 是什么意思 也无法使用Google找到合适的解释 有人可以提供一个演示类型级编程的示例吗 范式的解释和 或定义将
  • Android JUnit 测试中的运行时异常

    我有一个简单的 HelloWorld Activity 我尝试使用 Android JUnit 测试对其进行测试 应用程序本身按预期运行 但测试失败并显示 java lang RuntimeException 无法解析以下活动 Intent
  • 抛出并保留堆栈跟踪不符合代码分析所描述的预期

    进行代码分析给了我项目 CA2200 CA2200 重新抛出以保留堆栈详细信息 func 重新抛出捕获的异常并将其显式指定为参数 请改用不带参数的 throw 以保留最初引发异常的堆栈位置 我已经实现了该建议 但无论如何我似乎都得到了相同的
  • GetWindowText() 抛出错误并且没有被 try/catch 捕获

    当我为 GetWindowText 运行下面的代码时 我收到作为内部异常抛出的以下错误 尝试读取或写入受保护的内存 这通常表明其他内存已损坏 DllImport user32 dll EntryPoint GetWindowTextLeng
  • 第一次机会异常 - 在内存位置长?

    这是什么 我该如何处理 修复它 First chance exception at 0x756fb727 in Program exe Microsoft C exception long at memory location 0x0018
  • Liferay ClassNotFoundException:DLFileEntryImpl

    在我的 6 1 0 Portal 实例上 带有使用 ServiceBuilder 和 DL Api 的 6 1 0 SDK Portlet 这一行 DynamicQuery query DynamicQueryFactoryUtil for

随机推荐