44

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

上下文:我正在使用 GHC 7.10 和stack处理 64 位的 Windows 和 Linux 。RDFox 是用 C++ 编写的。可以使用 Java 和 Python 包装器下载 RDFox 共享库(.dll、.so)。

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

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

问题:我想知道:

  1. 如何配置 stack 和 cabal 以使用外部库,在 WindowsLinux 上构建(不同的机器,相同的存储库)。
  2. 如何配置 GHCi 以在此外部库上进行交互式测试。
  3. 将 Python 包装器翻译成 Haskell 是最好的方法吗?我想避免分析 RDFox C++ 代码。
4

3 回答 3

2
  1. 您需要像这样在文件的部分中使用extra-lib-dirs和:extra-librariesexecutable.cabal

    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只要它可以找到您的库(LD_LIBRARY_PATH在 linux 上)就可以工作。

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

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

    我强烈建议使用safeccalls,并且不要将函数包装在unsafePerformIO.

    如果您需要传递非不透明结构,您可能需要调查c2hsor hsc2hs,但我认为您不需要这样做。有关更多详细信息,请参阅此问题

于 2016-07-04T15:15:24.843 回答
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 函数

对于复合数据类型(类和结构),您需要在 Haskell 中创建 C++ 数据类型模拟。然后你需要描述如何将数据类型从 C++ 编组到 Haskell 以及从 Haskell 到 C++。

在 Haskell 中,这意味着您需要为您的数据类型创建 Storable 实例。

于 2016-07-15T15:04:20.423 回答
0

本文档的答案:

ghc -c Adder.hs
ghc -c StartEnd.c
ghc -shared -o Adder.dll Adder.o Adder_stub.o StartEnd.o
于 2016-07-04T04:15:16.720 回答