Edit: You should also see Tomer's answer below. My answer here describes the theory of what's going on, but I may have some of the details of execution incomplete, whereas his answer is a complete working example.
As sclv indicates, compiling should be no problem. The difficulty there is likely to be linking the C++ code, and here you will have a little bit of difficulty with getting all the needed runtime libraries linked in. The problem is that Haskell programs need to be linked with the Haskell runtime libraries, and C++ programs need to be linked with the C++ runtime libraries. In the Wiki page you reference, when they do
$ ghc -optc -O test.c A.o A_stub.o -o test
to compile the C program, that actually does two steps: It compiles the C program into an object file, and then links it together. Written out, that would be something like (probably not quite right, as I don't speak GHC):
$ ghc -c -optc-O test.c -o test.o
$ ghc test.o A.o A_stub.o -o test
GHC just acts like GCC (and, IIUC, functionally is GCC) when compiling the C program. When linking it, however, it is different from what happens if you call GCC directly, because it also magically includes the Haskell runtime libraries. G++ works the same way for C++ programs -- when it's used as a linker, it includes the C++ runtime libraries.
So, as I mentioned, you need to compile in a way that links with both runtime libraries. If you run G++ in verbose mode to compile and link a program, like so:
$ g++ test.cpp -o test -v
it will create a long list of output about what it's doing; at the end will be a line of output where it does the linking (with the collect2
subprogram) indicating what libraries it links to. You can compare that to the output for compiling a simple C program to see what's different for C++; on my system, it adds -lstdc++
.
Thus, you should be able to compile and link your mixed Haskell/C++ program like so:
$ ghc -c -XForeignFunctionInterface -O A.hs # compile Haskell object file.
$ g++ -c -O test.cpp # compile C++ object file.
$ ghc A.o A_stub.o test.o -lstdc++ -o test # link
There, because you've specified -lstdc++
, it will include the C++ runtime library (assuming -l
is the right GHC syntax; you'll need to check), and because you've linked with ghc
, it will include the Haskell runtime library. This should result in a working program.
Alternately, you should be able to do something similar to the -v
output investigation with GHC, and figure out what Haskell runtime library (or libraries) it links to for Haskell support, and then add that library when linking your program with C++, just as you already do for pure C++ programs. (See Tomer's answer for details of that, since that's what he did.)
extern "C"
, rely heavily on implicit conversion of void pointers, or named some variableclass
etc., I don't see why not. – asveikaug++
to link does not work any more. The new method seems to rely onghc
doing all compilation and linking. On ArchLinux:ghc --make -dynamic -no-hs-main test.cpp Foo.hs -lstdc++ -o test
– Roland Puntaier