I want to call a Haskell function that is operating on text and returns text (actually the processing is complicated and the Haskell code is split into few modules, but this probably isn't the case).
I tried the approach described here: Communication between Java and Haskell and modified it to work with Strings.
But I'm getting the error:
error: initializing argument 1 of ‘void* myFunction_hs(HsPtr)’ [-fpermissive]
extern HsPtr myFunction_hs(HsPtr a1);
^
The relevant code and compilation is here: in Haskell:
foreign export ccall myFunction_hs :: CString -> IO CString
in Java:
import com.googlecode.javacpp.*;
import com.googlecode.javacpp.annotation.*;
@Platform(include={"<HsFFI.h>","myModule_stub.h"})
public class MyModule {
static { Loader.load(); }
public static native void hs_init(int[] argc, @Cast("char***") @ByPtrPtr PointerPointer argv);
public static native String myFunction_hs(String text);
public static void main(String[] args) {
hs_init(null, null);
String s = myFunction_hs("This is some String.");
System.out.println("Result: " + s);
}
}
And the compilation:
$ ghc -fPIC -c -O myModule.hs
$ javac -cp javacpp.jar MyModule.java
$ java -jar javacpp.jar -Dcompiler.path=ghc -Dcompiler.output.prefix="-optc-O3 -Wall MyModule.o -dynamic -fPIC -shared -lstdc++ -lHSrts-ghc7.6.3 -o " -Dcompiler.linkpath.prefix2="-optl -Wl,-rpath," MyModule
Do you have any idea what goes wrong?
I managed to solve this issue.
You need to edit the myModule_stub.h file (it is automatically generated). In my case I had to change the line:
extern HsPtr myFunction_hs(HsPtr a1);
to:
extern char* myFunction_hs(const char* a1);
Of course, you should rename your myModule_stub.h
into myModule.h
after manual editing. Otherwise it will be overwritten by GHC, and your specific types will be lost.