从Haskell调用ARPACK ++(一个C ++库)会涉及什么?

时间:2012-08-07 04:25:27

标签: haskell

我花了几天时间在Haskell中开发一个程序,同时学习这门语言。现在我意识到我需要调用Arpack(Fortran库)或Arpack ++(Arpack的C ++包装器) - 我找不到使用Haskell绑定的Lanczos方法的良好实现。任何更有经验的Haskell程序员都会认为这会有多困难吗?

我已经能够通过Ubuntu的存储库获得libarpack和libarpack ++的“.so”(“共享对象”)版本,但我不确定这是否足够。我怀疑我最终需要从源代码构建Arpack ++,这是可能的,但是我遇到了很多构建错误,所以需要时间。有没有办法只使用“.so”文件,而不知道确切地使用哪个版本的头文件来生成它们?

我正在考虑使用GreenCard,因为它看起来像是维护得最好的Haskell / C桥。我找不到很多文档,所以我想知道它是否也会支持C ++。

我也开始怀疑我是否应该用Python重写我的程序,并使用scipy来调用Arpack,但是我已经写了几天来编写Haskell。我也非常喜欢Haskell,所以我希望我能做到这一点。我想我的总体问题是:使用Haskell进行这项工作会涉及什么?

非常感谢。

2 个答案:

答案 0 :(得分:1)

我可以告诉你,在外部函数接口的帮助下,使用Haskell的C / Fortran库肯定是可能的,并不是非常复杂。这是一个introduction。根据我的理解,您应该能够使用C调用约定调用任何内容,甚至可以调用Fortran,而无需重新编译代码。唯一的例外是看起来像函数调用但确实是宏的东西,在这种情况下你必须弄清楚宏做了什么并在Haskell中重现它们。

截至绿卡,我从未使用过它,所以我无法保证。

使用Python的第二个想法可能会为您节省超过两天的时间。虽然很难过,但我从未管理过Haskell代码以轻松适应我不断变化的需求,而我发现Python中的这些代码很简单。当然,这可能会限制我使用Haskell或我的思维过程的技能,而不是责怪语言。

答案 1 :(得分:1)

ELF格式是可执行文件和共享库的标准格式,因此访问这些已编译模块中的代码只需要知道函数名称。如果我理解正确,Fortran是interoperable with C。因此,Fortran应该可以与任何可以使用C绑定的语言互操作,包括Haskell。仅供参考,您可以使用nm工具找到由模块(可执行文件或共享对象或简单对象存档)导出的所有名称(默认情况下,它通常在所有Linux发行版中都可用)。如果二进制文件没有“剥离”,这当然会起作用,但AFAIK并不常见。

但是,Haskell不能以理智的方式使用C ++绑定,因为C ++多态特性需要name mangling,并且此名称转换的方法高度依赖于编译器。众所周知的问题不是Haskell特有的。当然,您可以尝试从C ++共享对象中获取导出符号的列表,然后使用FFI绑定它们,但是......这是不值得的。

正如dsign所说,您可以使用外部函数接口GHC功能来创建对外部代码的绑定。您需要的只是库标题(当然还有库本身)。如果C语言是头文件(* .h),但由于你的库是用Fortran编写的,你必须在库源中找到类似的头文件,引用this page来匹配Fortran和C类型,然后使用此信息编写FFI绑定。首先编写C绑定,即编写C头是有帮助的。然后你甚至可以使用像c2hs这样的自动FFI绑定程序。

查看C ++绑定可能也很有帮助。它可能有我上面描述的头文件。如果它有一个,那么编写FFI绑定并不比为其他任何库编写它们困难。

所以,这并非完全不可能,但可能需要一些彻底的工作。将编码绑定到科学/纯计算库比编写一些系统库更容易,这些系统库执行大量IO并保持其自己的内部状态,但由于这个库不是用C编写的......嗯,建议把时间花在更容易的替代品上。我不能说scipy,我从来没有使用它,但由于Python作为一种语言比Haskell简单得多,它可能是一个很好的选择。