18

是否可以将Haskell 代码嵌入C 库中,这样库的用户就不必知道正在使用Haskell?特别是,这样用户可以使用多个嵌入 Haskell 的库,而不会发生任何冲突?

据我了解,您嵌入了对 hs_init 和 hs_exit 的调用之间,但这些涉及全局状态恶作剧,应该与其他调用冲突,不是吗?

4

1 回答 1

14

是的,可以通过 FFI(外部函数接口)从 C 调用 Haskell 代码(反之亦然)。不幸的是,正如haskell.org 文档所说,您无法避免初始化和完成 haskell 环境的调用:

对 hs_init() 的调用初始化 GHC 的运行时系统。在调用 hs_init() 之前不要尝试调用任何 Haskell 函数:坏事无疑会发生。

但是,也很有趣:

可以对 hs_init() 进行多次调用,但每次调用都应与一次(并且只有一次)对 hs_exit() 的调用匹配

此外:_

FFI 规范要求实现支持在使用 hs_exit() 关闭后重新初始化自身,但 GHC 目前不支持。

基本上我的想法是,您可以利用此规范为自己编写一个包装 C++ 类来管理对您的调用hs_iniths_exit为您管理调用,例如通过使用包围的模板方法,hs_init并且hs_exit您可以使用您想要的任何 haskell 调用覆盖。但是,请注意与调用 haskell 代码的其他库的交互:对hs_init和的嵌套调用层hs_exit应该没问题(因此使用在包装器之间调用它们的库是安全的),但调用的总数应该始终匹配,这意味着如果这些库只初始化环境而不试图关闭它,然后由你来完成这项工作。

在不利用继承和覆盖的情况下,另一个(可能更好)的想法可能是拥有一个在构造函数和析构函数HaskellEnv中调用的简单类。如果您将它们声明为自动变量,您将获得对和的调用将始终匹配,并且当您离开其范围时,一旦最新对象被破坏,将立即进行最新调用。看看这个问题,以防止在堆上创建对象(在这种情况下它们可能很危险)。hs_iniths_exiths_iniths_exiths_exitHaskellEnv

于 2012-06-21T11:49:33.410 回答