簡體   English   中英

用C之間用Java調用Haskell

[英]Calling Haskell from Java with C in between

這可能聽起來像是一場噩夢,但我真的很想讓它發揮作用。 我大部分時間都在使用這個例子: 從Haskell調用C並嘗試在ubuntu上運行。

我在java中運行它:

package test;

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

在使用javah創建.h文件后的這個中:(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:在創建共享對象時,不能使用針對未定義符號“fibonacci_hs”的重定位R_X86_64_PC32; 使用-fPIC / usr / bin / ld重新編譯:最終鏈接失敗:錯誤值collect2:ld返回1退出狀態

我不是任何方式的專家,不知道該怎么做。 我嘗試用-fPIC編譯各種方法,但我繼續得到同樣的錯誤。 知道我可能做錯了什么嗎?

謝謝!

雖然我在這里幾乎回答了這個問題: Java和Haskell之間的通信 ,因為這個問題更多的是關於錯誤本身,我將在這里添加詳細信息。 問題源於Haskell不能很好地支持共享庫,而Java需要它們。 作為Haskell共享庫的建築物插件為我們提供了這種見解和解決方法:

原則上,您可以在鏈接步驟中使用-shared而不使用-dynamic。 這意味着將所有基礎庫靜態鏈接到新的共享庫中。 這將成為一個非常大但獨立的共享庫。 但是,這需要使用-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堆棧,但我很確定它們中的任何一個都可以在一個簡單的套接字上工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM