[Haskell-cafe] Basic FFI with GHC

Ronald Guida ronguida at mindspring.com
Tue Sep 11 14:57:15 EDT 2007


How do I create C-libraries that I can load into GHCi?  I am trying to
do some basic FFI, and it's not working.

Here's the background.  I created three files, foo.h, foo.cpp, and
test_foo.lhs. (source code below)

Note: I am using MinGW/Msys under Windows XP.

If I compile foo.cpp and then try to load test_foo into GHCi, I get an
error.  OTOH, if I compile test_foo with GHC, it works.  I just don't
understand why it works one way and not the other.

What am I doing wrong?

-- Ron

------------------------------
Shell commands
------------------------------

$ gcc -c foo.cpp

$ ghci test_foo.lhs foo.o
   ___         ___ _
  / _ \ /\  /\/ __(_)
 / /_\// /_/ / /  | |      GHC Interactive, version 6.6.1, for Haskell 98.
/ /_\\/ __  / /___| |      http://www.haskell.org/ghc/
\____/\/ /_/\____/|_|      Type :? for help.

Loading package base ... linking ... done.
Loading object (static) foo.o ... done
final link ... done
[1 of 1] Compiling Main             ( test_foo.lhs, interpreted )

During interactive linking, GHCi couldn't find the following symbol:
  foo
This may be due to you not asking GHCi to load extra object files,
[snip]

$ ghc --make test_foo.lhs foo.o
[1 of 1] Compiling Main             ( test_foo.lhs, test_foo.o )
Linking test_foo.exe ...

$ test_foo.exe
Entering main
y = 22
Exiting main

$ ar rcs libfoo.a foo.o

$ ghc --make test_foo.lhs -lfoo

$ test_foo.exe
Entering main
y = 22
Exiting main

$ ghci test_foo.lhs -lfoo
   ___         ___ _
  / _ \ /\  /\/ __(_)
 / /_\// /_/ / /  | |      GHC Interactive, version 6.6.1, for Haskell 98.
/ /_\\/ __  / /___| |      http://www.haskell.org/ghc/
\____/\/ /_/\____/|_|      Type :? for help.

Loading package base ... linking ... done.
Loading object (dynamic) foo ... failed.
Dynamic linker error message was:
   addDLL: unknown error
Whilst trying to load:  (dynamic) foo
Directories to search are:
: user specified .o/.so/.DLL could not be loaded.

------------------------------
Source code
------------------------------

// foo.h

extern "C"
{
  __stdcall int foo(int x);
}

------------------------------

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

__stdcall int foo(int x)
{
  return 3 * x + 1;
}

------------------------------

test_foo.lhs

 > {-# OPTIONS_GHC -fglasgow-exts #-}
 > module Main
 >     where
 > import Foreign
 > import Foreign.C

 > foreign import stdcall unsafe "foo"
 >   c_Foo :: Word32 -> IO Word32

 > main = do
 >   putStrLn "Entering main"
 >   let x = 7::Word32
 >   y <- c_Foo(x)
 >   putStrLn $ "y = " ++ show y
 >   putStrLn "Exiting main"




More information about the Haskell-Cafe mailing list