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