How to use DLL in a Haskell project?

I would like to use the external RDFox library in a Haskell project.

Context: I work on Windows and Linux, both with 64 bits, using GHC 7.10, and stack . RDFox is programmed in C ++. RDFox shared libraries (.dll, .so) can be loaded using Java and Python shells.

Purpose: I would like to reuse compiled libraries from RDFox (.dll, .so) in my project in Haskell, so I need to create a Haskell wrapper for RDFox.

Problems: Being relatively new to Haskell, I hardly know where to start. I found several related pages (from the Haskell wiki and StackOverflow), but the workflow and configuration are not clear to me.

Questions: I would like to know:

  • How to configure stack and cabal to use an external library, to create on Windows or Linux (different machines, the same repository).
  • How to configure GHCi for interactive testing of this external library.
  • Is translating a Python shell to Haskell the best way? I would like to avoid parsing RDFox C ++ code.
+42
haskell ghc shared-libraries cabal haskell-stack
Jul 03 '15 at 7:34
source share
3 answers
  • You need to use extra-lib-dirs and extra-libraries in the executable section of your .cabal file .cabal this:

     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 

    Put your dll and .so in lib . Be careful, you will run into link order problems if you use the static library ( .a instead of .so ) in linux.

    See this for an example. Don't be fooled by the name, as it works great with .so files.

  • stack ghci should only work if it can find your library ( LD_LIBRARY_PATH on Linux).

  • The C API (mentioned in the comments on your question) already exists. You just need to write FFI Haskell signatures, for example:

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

    I would highly recommend using safe ccalls and not porting functions to unsafePerformIO .

    If you need to pass opaque structures, you can study c2hs or hsc2hs , but I don't think you will need to. See question for details.

+1
Jul 04 '16 at 15:15
source share

You need to create a C-exported shell for the C ++ api and a Haskell shell for FFI in the C-exported shell.

Marshaling between C # and Haskell is described here: Haskell call with C #

but it is very similar to marshaling between C ++ and Haskell

For example, create a C ++ export function:

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

In Haskell, you need an import code:

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

Then you can use addFive in Haskell as a typical Haskell function

For composite data types (classes and structures) you need to create an analogue of the C ++ data type in Haskell. Then you need to describe how the marshal's data types are from C ++ to Haskell and from Haskell to C ++.

In Haskell, this means that you need to create a Storable instance for your data types.

+1
Jul 15 '16 at 15:04
source share

The answer is this documentation :

 ghc -c Adder.hs ghc -c StartEnd.c ghc -shared -o Adder.dll Adder.o Adder_stub.o StartEnd.o 
0
Jul 04 '16 at 4:15
source share



All Articles