是否有可能将Haskell不透明地嵌入到C库中?

时间:2012-06-21 11:45:42

标签: haskell

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

据我所知,你在hs_init和hs_exit的调用之间嵌入,但是这些涉及全局状态恶作剧并且应该与其他调用冲突,不是吗?

1 个答案:

答案 0 :(得分:14)

是的,通过FFI possible从C调用Haskell代码(反之亦然)是Foreign Function Interface。不幸的是,正如haskell.org docs所说,你无法避免调用初始化和最终确定haskell环境:

  

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

但是,this也很有趣:

  

可以多次调用hs_init(),但每个调用都应该是   匹配一个(只有一个)调用hs_exit()

furthermore

  

FFI规范要求实施支持重新初始化   在用hs_exit()关闭之后本身,但GHC没有   目前支持。

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

另一个(可能更好)的想法,没有利用继承和覆盖,可能是一个简单的类hs_exit,在构造函数中调用HaskellEnvhs_init在析构函数中。如果您将它们声明为自动变量,则您将获得始终匹配hs_exiths_init的来电,并且最新的hs_exit号呼叫将在最新时发出当你离开它的范围时,hs_exit对象被破坏。 看看this question以防止在堆上创建对象(在这种情况下它们可能很危险)。