4

I've create a static library:

// foo.h
extern "C" {
int foo (const char* arg0, int arg1);
}

// foo.cpp
#include "foo.h"
// implementation of foo

This block of code was compiled to foo.o and packaged into libfoo.a which was installed to MinGW's lib dir (I'm on Windows, using GCC toolchain).

What I want to do is to wrap this function in Haksell code, so a typical FFI binding as follows:

-- Foo.hs
{-# LANGUAGE ForeignFunctionInterface #-}
module Foo where

foreign import ccall "foo"
    c_foo :: CString -> CInt -> IO (CInt)

extra-libraries was added to the .cabal file as well:

...
extra-libraries: foo, stdc++

But GHC compains about undefined reference on foo:

.dist-scion\build\path\to\Foo.o:fake:(.text+0x514): undefined reference to `foo'

After nm the library to find out the function foo actually existing in the library (with some decorations on the name), I'm stucked here...


[EDIT]
I also tried build the haskell package using cabal:

cabal configure
cabal build

The result shows:

Loading object (dynamic) foo ... ghc.exe: foo: ....
<command line>: user specified .o/.so/.DLL could not be loaded (addDLL: could not load DLL)

So is this supposed to have something to do with static/dynamic linking? 'cause I noticed GHC want to load .o/.so/.DLL but NOT .a. I'm really confused.


finally got something on the wiki: Cxx Foreign Function Interface


[EDIT]
One solution is to use -optl-lfoo -optl-lstdc++ in .cabal file, not extra-libraries. And the naming problem can be easily solved by wrapping the declaration in extern "C":

#ifdef __cplusplus
extern "C" {
#endif

extern int foo (const char*, int);

#ifdef __cplusplus
}
#endif

This works within EclipseFP, 'cause it uses Scion. But it still fails on cabal build.

claude
  • 237
  • 1
  • 8
  • Since you're on Windows, I think you need to change the foreign import statement to `foreign import stdcall "foo"`. – John L Oct 17 '11 at 12:41
  • @JohnL : I use `nm` to inspect symbols in the .o file after adding `__stdcall` to the function, and get something like this: `00000000 T __Z18fooPKci@24`. GHC still says undefined reference to `foo@24`... – claude Oct 17 '11 at 12:57
  • 1
    @clause: that symbol is C++ name-mangled. Are you certain that `foo` is declared inside an `extern "C"` block? – Derrick Turk Oct 17 '11 at 14:31
  • @DerrickTurk: no. But at first it IS in an `extern "C"`. I did some experiments, try to use `foreign import stdcall`, and failed. – claude Oct 18 '11 at 02:31
  • 1
    @claude: I tried your original code and it works for me. I built the library with `g++ -c foo.cpp; ar rcs libfoo.a foo.o; ghc ghc -lfoo Foo.hs`. This is with g++-4.5.0 and ghc-7.0.3. Is some of your code using Template Haskell, either directly or via fclabels or similar? – John L Oct 18 '11 at 09:55
  • @JohnL: Yes, part of my code uses `peggy`, which involves `QuasiQuotations`. I suppose it is somehow TH related. – claude Oct 18 '11 at 10:35
  • @JohnL: I tried my original code. It works fine with cabal build at the first build. After I delete the dist folder and try cabal build again, it fails with `user specified .o/.so/.DLL could not be loaded` – claude Oct 18 '11 at 10:49
  • @claude: it may be TH related. Since TH seems to want a .dll, can you build a .dll instead of a static archive? – John L Oct 18 '11 at 14:35
  • @JohnL: If that's the case, it seems I don't have any other choice... thanks! – claude Oct 19 '11 at 02:59
  • @claude: I'm pretty sure I don't understand completely what's going on, so there may be something else involved. Can you share the full package, or an example which includes the peggy stuff? – John L Oct 19 '11 at 15:25
  • @JohnL: I can send an example package to you via email. – claude Oct 20 '11 at 07:10
  • @claude: sure, it's in my profile. It'll probably take me a few days to respond though. – John L Oct 20 '11 at 18:18
  • @JohnL: it seems we can't see each other's email address. – claude Oct 21 '11 at 02:55
  • @claude: ok, try here then http://www.blogger.com/profile/14086288462709102194 – John L Oct 21 '11 at 12:57
  • @claude: You've probably solved this, but I just ran into and solved a problem that sounds similar (http://stackoverflow.com/questions/18562881/attempting-a-c-binding-to-haskell-getting-undefined-reference-errors). – Deech Sep 02 '13 at 12:24

0 Answers0