
On Tue, 2005-09-13 at 15:20 +0000, Felix Breuer wrote:
we have tried long and hard to call Haskell functions from C++ using the FFI mechanism but without success.
$ ghc -fffi Foo.o Foo_stub.o main.cpp main.o(.text+0x22): In function `main': main.cpp: undefined reference to `__stginit_Foo()' main.o(.eh_frame+0x11): undefined reference to `__gxx_personality_v0' collect2: ld returned 1 exit status
Unless Haskell C header files do this (which they should!) you will have to do it yourself for each #include of a header file: extern "C" { #include <some C-only header file> } These header files provided by GHC should be fixed to use the standard artifice: #ifdef __cplusplus extern "C" { #endif rest of the file here ... #ifdef __cplusplus } #endif All C header files should be constructed this way. GNU headers use the macros __BEGIN_DECLS __END_DECLS The problem you are having is simple: C++ supports overloading, so a function called void fred(); in C is named 'fred' or '_fred' by the linker .. and that's that. In C++, you can have this fred and also void fred(int); so these functions have to have different names. They're called mangled or decorated names and are compiler dependent. extern "C" disables C++ name mangling by forcing everything to have the same linkage as the companion C compiler. [There are still some incompatibilities however .. hopefully you won't run into any of them] There is one more problem: you MUST NOT run gcc on files ending in *.cpp. You are REQUIRED to run g++. So you will have to somehow tell ghc to use g++ and NOT gcc. in particular C++ programs require different startup code to C, to initialise exception handling, etc etc. So the whole program MUST be linked by g++, not gcc, and the main() must be compiled with g++ not gcc. Note sure about GHC, but there is only one correct mainline: #ifdef __cplusplus extern "C" #endif int sub(int, char**); int main(int argc, char **argc) { return sub(argc,argv); } This should be the whole mainline .. because this is the only part of the system that must be compiled either as C++ or as C, the rest (called 'sub' above) can be compiled as C. This lets the client choose either C or C++ without burdening the vendor with having to compiled the real code using both. -- John Skaller <skaller at users dot sourceforge dot net>