首页 文章

如何在Haskell项目中使用DLL?

提问于
浏览
43

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

Context: 我正在使用GHC 7.10和stack在64位上运行Windows和Linux . RDFox用C编程 . 可以使用Java和Python包装器下载RDFox共享库(.dll,.so) .

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

Issues: 对Haskell来说相对较新,我很难知道从哪里开始 . 我找到了几个关于这个主题的页面(来自Haskell wiki和StackOverflow),但工作流程和配置对我来说并不清楚 .

Questions: 我想知道:

如何配置堆栈和cabal以使用外部库,在Windows或Linux(不同的机器,相同的存储库)上构建 . 如何在此外部库上配置GHCi以进行交互式测试 . 将Python包装器转换为Haskell是最好的方法吗?我想避免分析RDFox C代码 .

3 回答

  • 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 ),则会遇到链接顺序问题 .

    有关示例,请参阅this . 不要被名称所迷惑,因为它与 .so 文件一起正常工作 .

    • stack ghci 应该只是工作,只要它可以找到你的库(在Linux上 LD_LIBRARY_PATH ) .

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

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

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

    如果您需要传递非透明结构,您可能需要调查 c2hshsc2hs ,但我不需要这样做 . 有关更多详细信息,请参见question .

  • 1

    您需要为C api和Haskell包装器创建一个C导出的包装器到FFI到C导出的包装器 .

    C#和Haskell之间的编组在这里描述:Calling Haskell from C#

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

    例如,创建C导出功能:

    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数据类型(类和结构),您需要在Haskell中创建C数据类型模拟 . 然后,您需要描述如何编组从C到Haskell以及从Haskell到C的数据类型 .

    在Haskell中,这意味着您需要为数据类型创建可存储实例 .

  • 0

    答案来自this documentation

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

相关问题