从C中调用Java的Haskell

这可能听起来像一场噩梦,但我真的想要得到这个工作。 我使用这个例子大部分: 从Haskell调用C,并试图让这个工作在Ubuntu上。

我在java中运行这个:

package test; public class JniTest { public native int fib(int x); } 

这个在用javah创build.h文件之后在c:(test_JniTest.c)

 #include "test_JniTest.h" #include "Safe_stub.h" JNIEXPORT jint JNICALL Java_test_JniTest_fib(JNIEnv * e, jobject o, jint f) { return fibonacci_hs(f); } 

然后在Haskell中(在存根之前)引用:(Safe.hs)

 module Safe where import Foreign.C.Types fibonacci :: Int -> Int fibonacci n = fibs !! n where fibs = 0 : 1 : zipWith (+) fibs (tail fibs) fibonacci_hs :: CInt -> CInt fibonacci_hs = fromIntegral . fibonacci . fromIntegral foreign export ccall fibonacci_hs :: CInt -> CInt 

这就是我正在试图编译它:

ghc -c -O Safe.hs

其次是:

ghc -shared -o libTest.jnilib -optc -o test_JniTest.c -I / usr / lib / jvm / java-6-sun-1.6.0.26 / include -I / usr / lib / jvm / java-6-sun- 1.6.0.26/include/linux

我得到这个错误:

/ usr / bin / ld:test_JniTest.o:重新定位R_X86_64_PC32与未定义的符号`fibonacci_hs'在制作共享对象时无法使用; 使用-fPIC / usr / bin / ld重新编译:最终链接失败:错误值collect2:ld返回1退出状态

我不是什么专家,也不知道该怎么做。 我尝试用-fPIC编译各种方法,但是我一直在得到相同的错误。 任何想法我可能做错了什么?

谢谢!

Solutions Collecting From Web of "从C中调用Java的Haskell"

尽管我已经在这里回答了这个问题: Java和Haskell之间的通信 ,因为这个问题更多的是关于错误本身,我将在这里添加细节。 这个问题源于Haskell不支持共享库,而Java则需要它们。 Haskell共享库的建筑插件为我们提供了这种见解和解决方法:

原则上你可以在链接步骤中使用没有-dynamic的-shared。 这意味着将所有基础库的静态链接到新的共享库中。 这将是一个非常大的,但独立的共享库。 但是,这将需要所有的静态库已经与-fPIC构建,以便代码适合包括到共享库,我们现在不这样做。

如果我们再次使用ldd来查看我们所做的libfoo.so,我们会注意到它缺少对rts库的依赖。 这是我们尚未解决的问题,所以目前我们可以自己添加依赖关系:

 $ ghc --make -dynamic -shared -fPIC Foo.hs -o libfoo.so \ -lHSrts-ghc6.11 -optl-Wl,-rpath,/opt/ghc/lib/ghc-6.11/ 

这是一个解决方法,因为它要求我们在构建时知道rts库的版本。

如果你的目标是实际完成某些事情(而不是简单地使用JNI),我建议把它作为一个花园变种的RPC问题来解决,并且利用其中的一个框架/协议:

来自Google的协议缓冲区

从Facebook节俭

Avro(好吧,这主要是一个有线协议)

从你正在做的事情来看,Thrift可能是你最好的选择,因为它描述了一个完整的客户端/服务器RPC栈,但是我很确定他们中的任何一个都可以在一个简单的套接字上工作。