从C中调用Java的Haskell [英] Calling Haskell from Java with C in between

查看:121
本文介绍了从C中调用Java的Haskell的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这可能听起来像一场噩梦,但我真的想让这个工作。我大部分都使用这个例子:从Haskell调用C ,并试图在ubuntu上运行。 p>

我在java中运行它:

  package test; 

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

在使用javah创建.h文件之后,在c中:(test_JniTest.c )

  #includetest_JniTest.h
#includeSafe_stub.h

JNIEXPORT jint JNICALL Java_test_JniTest_fib(JNIEnv * e,jobject o,jint f)
{
return fibonacci_hs(f);

$ / code>

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

 模块安全其中

导入Foreign.C.Types

斐波纳契:: Int - > Int
fibonacci n = fibs !! n
其中fibs = 0:1:zipWith(+)fibs(尾纤)

fibonacci_hs :: CInt - > CInt
fibonacci_hs = fromIntegral。斐波纳契。 fromIntegral

国外出口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:搬迁对$ b R_X86_64_PC32 $ b未定义符号`fibonacci_hs'在制作共享的
对象时不能使用;使用-fPIC / usr / bin / ld重新编译:最终链接失败:错误值
collect2:ld返回1退出状态

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



谢谢!

解决方案

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


原则上,您可以在链接步骤中使用没有-dynamic的-shared。这意味着将所有基础库的静态链接到新的共享库中。这将会形成一个非常大但独立的共享库。然而,这将需要所有的静态库都使用-fPIC构建,以便代码适合包含到共享库中,而我们目前不这样做。



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

  $ ghc --make -dynamic -fPIC -shared -o Foo.hs \ libfoo.so 
-lHSrts-ghc6.11 -optl-WL,-rpath为/ opt / GHC / lib中/ ghc6.11 /


这是一种解决方法,因为它要求我们知道rts的版本图书馆在建设时间。


This probably sounds like a nightmare, but I'd really like to get this working. I am using this example for the most part: Calling C from Haskell and am trying to get this working on ubuntu.

I am running this in java:

package test;

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

this in c after creating the .h file with javah: (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);
}

and then for reference in haskell (before stub): (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

and this is what i'm trying to compile it with:

ghc -c -O Safe.hs

followed by:

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

and I am getting this error:

/usr/bin/ld: test_JniTest.o: relocation R_X86_64_PC32 against undefined symbol `fibonacci_hs' can not be used when making a shared object; recompile with -fPIC /usr/bin/ld: final link failed: Bad value collect2: ld returned 1 exit status

I am not a c expert by any means and have no idea what to do about this. I tried compiling various ways with -fPIC, but I kept on getting the same error. Any idea what I might be doing wrong?

Thanks!

解决方案

Although I've pretty much answered this question here: Communication between Java and Haskell, since this issue is more about the error itself, I will be adding the details for that here. The issue stems from Haskell not supporting shared libraries very well, while Java requires them. Buildings plugins as Haskell shared libs gives us this insight and workaround:

In principle you can use -shared without -dynamic in the link step. That would mean to statically link the rts all the base libraries into your new shared library. This would make a very big, but standalone shared library. However that would require all the static libraries to have been built with -fPIC so that the code is suitable to include into a shared library and we don't do that at the moment.

If we use ldd again to look at the libfoo.so that we've made we will notice that it is missing a dependency on the rts library. This is problem that we've yet to sort out, so for the moment we can just add the dependency ourselves:

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

This is a workaround because it requires us to know the version of the rts library at build time.

这篇关于从C中调用Java的Haskell的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆