FFI: calling Haskell from C++?
skaller
skaller at users.sourceforge.net
Tue Sep 13 12:07:52 EDT 2005
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>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part
Url : http://www.haskell.org//pipermail/glasgow-haskell-users/attachments/20050914/2c736c81/attachment.bin
More information about the Glasgow-haskell-users
mailing list