我正在尝试使用JavaCPP从Java调用Haskell代码,以帮助创建必要的JNI绑定,如本问题所述。
这就是我的使用方式:
<rootdir>
/javacpp.jar
/build (destination of libraris)
/src (contains Haskell code)
/com/example/HSCode.java (Java class to load and use native lib)
内容HScode.java
:
package com.example;
import org.bytedeco.javacpp.*;
import org.bytedeco.javacpp.annotation.*;
import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
@Platform(include={"<HsFFI.h>","HScode_stub.h"})
public class HScode {
static { Loader.load(); }
public static native void hs_init(int[] argc, @Cast("char***") @ByPtrPtr PointerPointer argv);
public static native String code_hs(String text);
public static void main(String[] args) throws FileNotFoundException {
String s = new Scanner(new File("test.txt")).useDelimiter("\\Z").next();
hs_init(null, null);
String s1 = code_hs(s);
System.out.println(s1);
}
}
汇编:
cd <rootdir>
ghc --make -isrc -dynamic -shared -fPIC src/HScode.hs \
-o build/libHScode.so -lHSrts-ghc7.8.4 -optl-Wl,-rpath,.
javac -cp javacpp.jar com/example/HScode.java
java -jar javacpp.jar -d build \
-Dplatform.compiler=ghc -Dplatform.includepath="src:com/example" \
-Dplatform.compiler.output="-optl-Wl,-rpath,. -optc-O3 -Wall build/libHScode.so -dynamic -fPIC -shared -lstdc++ -lHSrts-ghc7.8.4 -o " com.example.HScode
按照这种方法,我可以创建一个libHScode.so
和一个libjniHScode.so
using javacpp
,它可以很好地运行:
$ java -cp javacpp.jar:. com.example.HScode
现在,接下来的步骤是,我要将所有内容打包到一个jar中,并能够在com.example.HScode
较大的Java项目中使用此jar 。
JavaCPP的页面提到:
[...]此外,在运行时,Loader.load()方法自动从Java资源加载本机库,这些资源在构建过程中位于正确的目录中。它们甚至可以存档在JAR文件中,它什么也不会改变。用户根本不需要弄清楚如何使系统加载文件。
所以我认为这应该可行。
但是,如果我HScode.jar
根据上述build
文件夹的内容制作了一个jar ,以便我的jar同时包含libjniHScode.so
和libHScode.so
,并使用以下命令运行它:
$ java -cp javacpp.jar:HScode.jar:. com.example.HScode
那么它找不到我的本机代码(为匿名化而编辑的例外):
Exception in thread "main" java.lang.UnsatisfiedLinkError: no jniHScode in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1865)
at java.lang.Runtime.loadLibrary0(Runtime.java:870)
at java.lang.System.loadLibrary(System.java:1122)
at org.bytedeco.javacpp.Loader.loadLibrary(Loader.java:597)
at org.bytedeco.javacpp.Loader.load(Loader.java:438)
at org.bytedeco.javacpp.Loader.load(Loader.java:381)
at com.example.HScode.<clinit>(HScode.java:13)
Caused by: java.lang.UnsatisfiedLinkError: /compilation-path/linux-x86_64/libjniHScode.so: HScode.so: cannot open shared object file: No such file or directory
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1937)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1822)
at java.lang.Runtime.load0(Runtime.java:809)
at java.lang.System.load(System.java:1086)
at org.bytedeco.javacpp.Loader.loadLibrary(Loader.java:580)
我想念什么?有谁知道JavaCPP在jar中存档时是否真的可以找到本机代码?
通过调用本地库进行构建,方法是自动将其javacpp -jar javacpp.jar com.example.HScode
输出com/example/linux-x86_64/
并Loader
从那里加载。因此,当通过其他方式构建本机库时com/example/linux-x86_64/
,如果我们希望Loader
找到它们,则无论是将其存储在JAR文件中还是将其存储为普通文件,都仍然需要将它们移动到。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句