本文介绍了Java和Haskell之间的通信的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 我搜索了一些答案,可以通过GCJNI(现在网站已关闭)和LambdaVM完成Java与Haskell之间的通信。要使用LambdaVM / GCJNI,是否需要下载任何构建工具?我在哪里可以了解更多关于他们的信息,因为我没有在网上找到很多资源? 我想开发一个在Java和Haskell之间进行通信的应用程序(我将从Java的输入中将其传递给Haskell并在那里处理并返回结果Java)。这是我想要做的。请帮助我... 解决方案 从C调用Haskell看起来很容易,因此也可以通过 JavaCPP 的。例如,要从示例代码 Safe.hs 中调用 fibonacci_hs()函数: { - #LANGUAGE ForeignFunctionInterface# - } 模块安全其中 导入Foreign.C。类型 fibonacci :: Int - > Int fibonacci n = fibs !! n 其中fibs = 0:1:zipWith(+)fibs(尾纤) fibonacci_hs :: CInt - > CInt fibonacci_hs = fromIntegral。斐波纳契。 fromIntegral 国外出口ccall fibonacci_hs :: CInt - > CInt 我们可以用Java这种方式完成它: import org.bytedeco.javacpp。*; import org.bytedeco.javacpp.annotation。*; @Platform(include = {< HsFFI.h>,Safe_stub.h}) public class Safe { static {Loader.load(); } public static native void hs_init(int [] argc,@Cast(char ***)@ByPtrPtr PointerPointer argv); public static native int fibonacci_hs(int i); public static void main(String [] args){ hs_init(null,null); int i = fibonacci_hs(42); System.out.println(Fibonacci:+ i); $ / code> 在Linux下,编译过程如下所示: / p> $ ghc -fPIC -dynamic -c -O Safe.hs $ javac -cp javacpp.jar Safe.java $ java -jar javacpp.jar -Dplatform.compiler = ghc -Dplatform.compiler.output = - optc-O3 -Wall Safe.o -dynamic -fPIC -shared -lstdc ++ -lHSrts-ghc7.6.3 -o -Dplatform.linkpath.prefix2 = - optl -Wl,-rpath,Safe 程序通常使用通常的 java 命令运行: $ java -cp javacpp.jar :. Safe Fibonacci:267914296 编辑 strong>:我冒昧地做了一些调用开销的微观基准。使用以下C头文件 Safe.h : inline int fibonacci_c (int n){ return n< 2? n:fibonacci_c(n - 1)+ fibonacci_c(n - 2); } 以下Java类: import org.bytedeco.javacpp。*; import org.bytedeco.javacpp.annotation。*; $ b @Platform(include = {< HsFFI.h>,Safe_stub.h,Safe.h}) public class Safe { static { Loader.load方法(); } public static native void hs_init(int [] argc,@Cast(char ***)@ByPtrPtr PointerPointer argv); public static native int fibonacci_hs(int i); public static native int fibonacci_c(int n); public static int fibonacci(int n){ return n< 2? n:斐波纳契(n - 1)+斐波纳契(n - 2); } public static void main(String [] args){ hs_init(null,null); for(int i = 0; i fibonacci_hs(0); fibonacci_c(0); fibonacci(0); } long t1 = System.nanoTime(); for(int i = 0; i< 1000000; i ++){ fibonacci_hs(0); } long t2 = System.nanoTime(); for(int i = 0; i< 1000000; i ++){ fibonacci_c(0); } long t3 = System.nanoTime(); for(int i = 0; i< 1000000; i ++){ fibonacci(0); } long t4 = System.nanoTime(); System.out.println(fibonacci_hs(0):+(t2 - t1)/ 1000000 +ns); System.out.println(fibonacci_c(0):+(t3 - t2)/ 1000000 +ns); System.out.println(fibonacci(0):+(t4 - t3)/ 1000000 +ns); } } 用Intel Core i7-3632QM CPU @ 2.20GHz,Fedora 20 x86_64,GCC 4.8.3,GHC 7.6.3和OpenJDK 8: fibonacci_hs(0): 200 ns fibonacci_c(0):9 ns fibonacci(0):2 ns 平心而论,我应该提到将调用到 JVM也是相当昂贵的... 更新:最近对JavaCPP进行的更改用户现在可以通过C / C ++中的名称访问回调函数(指针),从而可以轻松地从Haskell调用JVM。例如,根据 wiki页面上有关Haskell的FFI 的信息,并将下列代码放入 Main.hs : { - #LANGUAGE ForeignFunctionInterface# - } 模块Main其中 导入Foreign.C - 获取C类型导入Foreign.Ptr(Ptr,nullPtr) - 不纯函数 foreign import ccallJavaCPP_initc_javacpp_init :: CInt - > Ptr(Ptr CString) - > IO() javacpp_init :: IO() javacpp_init = c_javacpp_init 0 nullPtr - 纯函数外部导入ccallfibonaccic_fibonacci :: CInt - > ; CInt fibonacci :: Int - > Int fibonacci i = fromIntegral(c_fibonacci(fromIntegral i)) main = do javacpp_init print $ fibonacci 42 和Java中这样定义的 fibonacci 函数: import org.bytedeco.javacpp。*; import org.bytedeco.javacpp.annotation。*; @Platform public class Main { public static class Fibonacci extends FunctionPointer { public @Name(fibonacci)int call(int n){ return n $ / code $ / pre 我们可能在Linux x86_64下构建类似于: $ javac -cp javacpp.jar Main.java $ java -jar javacpp.jar Main -header $ ghc --make Main.hs linux-x86_64 / libjniMain.so 并且程序正确地执行这个输出: $ ./Main 267914296 I googled and got some answers that communication between Java and Haskell can be done by GCJNI(Now the site is down) and LambdaVM.. To use the LambdaVM/GCJNI, whether I need to download any build tools? Where can I know more about them, since I don't find much resources on online?I want to develop an application that communicates between Java and Haskell(Where I will get the input from Java pass it to the Haskell and process there and return the result back to Java).This is what I want to do. Please help me... 解决方案 Calling Haskell from C appears quite easy, and thus can also be easily called from Java with JavaCPP. For example, to call the fibonacci_hs() function from the sample code Safe.hs:{-# LANGUAGE ForeignFunctionInterface #-}module Safe whereimport Foreign.C.Typesfibonacci :: Int -> Intfibonacci n = fibs !! n where fibs = 0 : 1 : zipWith (+) fibs (tail fibs)fibonacci_hs :: CInt -> CIntfibonacci_hs = fromIntegral . fibonacci . fromIntegralforeign export ccall fibonacci_hs :: CInt -> CIntwe can do it this way from Java:import org.bytedeco.javacpp.*;import org.bytedeco.javacpp.annotation.*;@Platform(include={"<HsFFI.h>","Safe_stub.h"})public class Safe { static { Loader.load(); } public static native void hs_init(int[] argc, @Cast("char***") @ByPtrPtr PointerPointer argv); public static native int fibonacci_hs(int i); public static void main(String[] args) { hs_init(null, null); int i = fibonacci_hs(42); System.out.println("Fibonacci: " + i); }}Under Linux, the compilation procedure looks like this:$ ghc -fPIC -dynamic -c -O Safe.hs$ javac -cp javacpp.jar Safe.java$ java -jar javacpp.jar -Dplatform.compiler=ghc -Dplatform.compiler.output="-optc-O3 -Wall Safe.o -dynamic -fPIC -shared -lstdc++ -lHSrts-ghc7.6.3 -o " -Dplatform.linkpath.prefix2="-optl -Wl,-rpath," SafeAnd the program runs normally with the usual java command:$ java -cp javacpp.jar:. SafeFibonacci: 267914296Edit: I have taken the liberty to do some microbenchmarking of the calling overhead. With the following C header file Safe.h:inline int fibonacci_c(int n) { return n < 2 ? n : fibonacci_c(n - 1) + fibonacci_c(n - 2);}the following Java class:import org.bytedeco.javacpp.*;import org.bytedeco.javacpp.annotation.*;@Platform(include={"<HsFFI.h>","Safe_stub.h", "Safe.h"})public class Safe { static { Loader.load(); } public static native void hs_init(int[] argc, @Cast("char***") @ByPtrPtr PointerPointer argv); public static native int fibonacci_hs(int i); public static native int fibonacci_c(int n); public static int fibonacci(int n) { return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2); } public static void main(String[] args) { hs_init(null, null); for (int i = 0; i < 1000000; i++) { fibonacci_hs(0); fibonacci_c(0); fibonacci(0); } long t1 = System.nanoTime(); for (int i = 0; i < 1000000; i++) { fibonacci_hs(0); } long t2 = System.nanoTime(); for (int i = 0; i < 1000000; i++) { fibonacci_c(0); } long t3 = System.nanoTime(); for (int i = 0; i < 1000000; i++) { fibonacci(0); } long t4 = System.nanoTime(); System.out.println("fibonacci_hs(0): " + (t2 - t1)/1000000 + " ns"); System.out.println("fibonacci_c(0): " + (t3 - t2)/1000000 + " ns"); System.out.println("fibonacci(0): " + (t4 - t3)/1000000 + " ns"); }}outputs this with an Intel Core i7-3632QM CPU @ 2.20GHz, Fedora 20 x86_64, GCC 4.8.3, GHC 7.6.3, and OpenJDK 8:fibonacci_hs(0): 200 nsfibonacci_c(0): 9 nsfibonacci(0): 2 nsIn all fairness, I should mention that it is also pretty expensive to call into the JVM as well...Update: With recent changes to JavaCPP, users can now access callback function (pointers) by name from C/C++, making it possible to call into the JVM from Haskell easily. For example, based on information found on a wiki page regarding Haskell's FFI, with the following code placed in Main.hs:{-# LANGUAGE ForeignFunctionInterface #-}module Main whereimport Foreign.C -- get the C typesimport Foreign.Ptr (Ptr,nullPtr)-- impure functionforeign import ccall "JavaCPP_init" c_javacpp_init :: CInt -> Ptr (Ptr CString) -> IO ()javacpp_init :: IO ()javacpp_init = c_javacpp_init 0 nullPtr-- pure functionforeign import ccall "fibonacci" c_fibonacci :: CInt -> CIntfibonacci :: Int -> Intfibonacci i = fromIntegral (c_fibonacci (fromIntegral i))main = do javacpp_init print $ fibonacci 42and a fibonacci function defined in Java this way:import org.bytedeco.javacpp.*;import org.bytedeco.javacpp.annotation.*;@Platformpublic class Main { public static class Fibonacci extends FunctionPointer { public @Name("fibonacci") int call(int n) { return n < 2 ? n : call(n - 1) + call(n - 2); } }}we may build under Linux x86_64 with something like:$ javac -cp javacpp.jar Main.java$ java -jar javacpp.jar Main -header$ ghc --make Main.hs linux-x86_64/libjniMain.soand the program executes correctly giving this output:$ ./Main267914296 这篇关于Java和Haskell之间的通信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!