即是否可以将Haskell 代码嵌入C 库中,这样库的用户就不必知道正在使用Haskell?特别是,这样用户可以使用多个嵌入 Haskell 的库,而不会发生任何冲突?
据我了解,您嵌入了对 hs_init 和 hs_exit 的调用之间,但这些涉及全局状态恶作剧,应该与其他调用冲突,不是吗?
即是否可以将Haskell 代码嵌入C 库中,这样库的用户就不必知道正在使用Haskell?特别是,这样用户可以使用多个嵌入 Haskell 的库,而不会发生任何冲突?
据我了解,您嵌入了对 hs_init 和 hs_exit 的调用之间,但这些涉及全局状态恶作剧,应该与其他调用冲突,不是吗?
是的,可以通过 FFI(外部函数接口)从 C 调用 Haskell 代码(反之亦然)。不幸的是,正如haskell.org 文档所说,您无法避免初始化和完成 haskell 环境的调用:
对 hs_init() 的调用初始化 GHC 的运行时系统。在调用 hs_init() 之前不要尝试调用任何 Haskell 函数:坏事无疑会发生。
但是,这也很有趣:
可以对 hs_init() 进行多次调用,但每次调用都应与一次(并且只有一次)对 hs_exit() 的调用匹配
此外:_
FFI 规范要求实现支持在使用 hs_exit() 关闭后重新初始化自身,但 GHC 目前不支持。
基本上我的想法是,您可以利用此规范为自己编写一个包装 C++ 类来管理对您的调用hs_init
和hs_exit
为您管理调用,例如通过使用包围的模板方法,hs_init
并且hs_exit
您可以使用您想要的任何 haskell 调用覆盖。但是,请注意与调用 haskell 代码的其他库的交互:对hs_init
和的嵌套调用层hs_exit
应该没问题(因此使用在包装器之间调用它们的库是安全的),但调用的总数应该始终匹配,这意味着如果这些库只初始化环境而不试图关闭它,然后由你来完成这项工作。
在不利用继承和覆盖的情况下,另一个(可能更好)的想法可能是拥有一个在构造函数和析构函数HaskellEnv
中调用的简单类。如果您将它们声明为自动变量,您将获得对和的调用将始终匹配,并且当您离开其范围时,一旦最新对象被破坏,将立即进行最新调用。看看这个问题,以防止在堆上创建对象(在这种情况下它们可能很危险)。hs_init
hs_exit
hs_init
hs_exit
hs_exit
HaskellEnv