如何在Haskell项目中使用DLL?

我想在Haskell项目中使用外部库RDFox 。

上下文:我正在使用GHC 7.10和堆栈 ,都是64位的Windows和Linux。 RDFox是用C ++编程的。 RDFox共享库(.dll,.so)可以用Java和Python包装下载。

目标:我想在我的Haskell项目中重用RDFox(.dll,.so)编译的库,所以我需要为RDFox创build一个Haskell包装器。

问题:对于Haskell来说相对较新,我很难知道从哪里开始。 我find了关于这个主题的几个页面(来自Haskell wiki和StackOverflow),但是工作stream和configuration对我来说并不清楚。

问题:我想知道:

  1. 如何configuration堆栈和cabal使用外部库,build立在Windows Linux(不同的机器,相同的存储库)。
  2. 如何在此外部库上configurationGHCi进行交互式testing。
  3. Python包装器翻译成Haskell是最好的方法吗? 我想避免对RDFox C ++代码的分析。
  1. 您需要在.cabal文件的executable部分中使用extra-lib-dirsextra-libraries ,如下所示:

     name: MyApp version: 0.1.0.0 synopsis: homepage: author: simon.bourne category: build-type: Simple cabal-version: >=1.10 library exposed-modules: HelloWorld build-depends: base >= 4.7 && < 5 hs-source-dirs: src default-language: Haskell2010 executable MyApp main-is: Main.hs extra-lib-dirs: lib extra-libraries: helloWorld build-depends: base >= 4.7 && < 5, MyApp hs-source-dirs: app default-language: Haskell2010 

    把你的dll和.so放在lib 。 被警告,如果你在linux上使用静态库( .a而不是.so ),你会遇到链接顺序问题。

    看到这个例子。 不要被这个名字所迷惑,因为它可以和.so文件一起工作。

  2. stack ghci应该只是工作,只要它能find你的库(Linux上的LD_LIBRARY_PATH )。

  3. C API(在您的问题的评论中提到)已经在那里。 您只需要编写Haskell FFI签名,例如:

     foreign import ccall safe "helloWorld" c_helloWorld :: IO () 

    我非常强烈地build议使用safe ccalls,并且不要将函数包装在unsafePerformIO

    如果你需要传递非不透明的结构,你可能想要调查c2hshsc2hs ,但我认为你不需要。 看到这个问题的更多细节。

您需要为C ++ api和Haskell包装器创build一个C导出的包装器,将其包装为FFI到C导出的包装器。

在这里描述的C#和Haskell之间的封送: 从C#调用Haskell

但它与C ++和Haskell之间的编组非常相似

例如,创buildC ++导出函数:

 extern "C" __declspec(dllexport) int __cdecl addFive(int number); extern "C" __declspec(dllexport) int __cdecl addFive(int number) { return number + 5; } 

在Haskell中,你需要导入代码:

 foreign import ccall "addFive" addFive :: Int -> Int 

然后你可以使用Haskell中的addFive作为典型的Haskell函数

对于compbound数据types(类和结构),您需要在Haskell中创buildC ++数据types模拟。 然后,您需要描述从C ++到Haskell以及从Haskell到C ++的编组数据types。

在Haskell中,这意味着您需要为您的数据types创buildStorable实例。

从这个文档回答:

 ghc -c Adder.hs ghc -c StartEnd.c ghc -shared -o Adder.dll Adder.o Adder_stub.o StartEnd.o