Ronald Guida wrote:
> 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.

So, after more searching on the internet and some RTFM, I think I
found my answer, and it seems to work, but I don't know if it's the
right answer to generalize from.

1. I can leave "test_foo.lhs" and "foo.cpp" as-is.

2. I need to change "foo.h" to the following:

------------------
// foo.h

#if BUILD_DLL
#define DECLSPEC __declspec(dllexport)
#else
#define DECLSPEC __declspec(dllimport)
#endif

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

3. I need to create a DEF file and list the functions to be exported
  in a DLL.

------------------
 foo.def
------------------
LIBRARY foo
DESCRIPTION "Foo Library"
EXPORTS
  foo
------------------

Note: The library name on the first line must match the dll name.
      "LIBRARY foo" corresponds to "foo.dll"

4. The build process is as follows.

(1) gcc -DBUILD_DLL -c foo.cpp

(2) gcc -shared -o foo.dll foo.o foo.def \
   -Wl,--enable-stdcall-fixup,--out-implib,libfoo.a

5. At this point, I'll have "foo.dll" and "libfoo.a".  I can load my
  "foo" library, as a DLL, into GHCi with the command:
    $ ghci -lfoo
  In reality, I would use:
    $ ghci test_foo.lhs -lfoo

6. Once I'm satisfied and ready to compile:

   ghc --make test_foo.lhs -L. -lfoo

Notes:
(1) "-L." directs GHC to look in the current directory for
    libraries.  GHCi seems to look there by default.

(2) The resulting "test_foo.exe" will dynamicly load "foo.dll".

7. If I want a staticly linked executable instead:

   ar rcs libfoo_static.a foo.o
   ghc --make test_foo.lhs -L. -lfoo_static

8. Finally, I can put the build steps into a makefile.

------------------
# Makefile for foo

test_foo.exe : test_foo.lhs libfoo.a foo.dll
   ghc --make test_foo.lhs -L. -lfoo

test_foo_static.exe : test_foo.lhs libfoo_static.a
   ghc --make test_foo.lhs -L. -lfoo_static -o test_foo_static.exe

libfoo.a : foo.dll

foo.dll : foo.o foo.def
   gcc -shared -o foo.dll foo.o foo.def \
   -Wl,--enable-stdcall-fixup,--out-implib,libfoo.a

libfoo_static.a : foo.o
   ar rcs libfoo_static.a foo.o

foo.o : foo.cpp foo.h
   gcc -DBUILD_DLL -c foo.cpp

.PHONY: clean
clean:
   rm -f *.[oa]
   rm -f *.dll
   rm -f *.hi
   rm -f *.exe
------------------

-- Ron

_______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to