44

Haskell プロジェクトで外部ライブラリRDFoxを使用したいと考えています。

コンテキスト: GHC 7.10 とstackを使用して、64 ビットの Windows と Linux で作業しています。RDFox は C++ でプログラミングされています。RDFox 共有ライブラリ (.dll、.so) は、Java および Python ラッパーと共にダウンロードできます。

目的: RDFox のコンパイル済みライブラリ (.dll、.so) を Haskell のプロジェクトで再利用したいので、RDFox 用の Haskell ラッパーを作成する必要があります。

問題: Haskell に比較的慣れていないので、どこから始めればよいかわかりません。このテーマに関するページをいくつか見つけました (Haskell wiki および StackOverflow から) が、ワークフローと構成は明確ではありません。

質問:私は知りたいです:

  1. WindowsまたはLinux (異なるマシン、同じリポジトリ) でビルドするために、外部ライブラリを使用するように stack と cabal を構成する方法。
  2. この外部ライブラリでインタラクティブなテストを行うために GHCi を構成する方法。
  3. Python ラッパーを Haskell に変換するのが最善の方法ですか? RDFox C++ コードの分析を避けたいと思います。
4

3 に答える 3

2
  1. 次のように、ファイルのセクションでextra-lib-dirsandを使用する必要があります。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_PATHLinux上で)動作するはずです。

  3. C API (質問のコメントに記載されています) は既に存在します。Haskell FFI 署名を記述するだけです。たとえば、次のようになります。

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

    ccallsを使用することを強くお勧めします。safe関数を でラップしないでくださいunsafePerformIO

    不透明でない構造体を渡す必要がある場合は、c2hsorを調査することをお勧めしhsc2hsますが、その必要はないと思います。詳細については、この質問を参照してください。

于 2016-07-04T15:15:24.843 に答える
1

C++ API 用の C エクスポート ラッパーと、FFI から C エクスポート ラッパーへの Haskell ラッパーを作成する必要があります。

ここで説明されている 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 に答える