我的代码与Trouble with compiling JNI完全相同。事实上,有同样的问题。尝试使用两步法解决问题,该方法运行如下:
cc -c HelloWorld.c
然后是下一个命令:
cc -shared -o libHelloWorld.so HelloWorld.o
第一个运行find并创建HelloWorld.o,但是,在运行第二个命令后,我收到此错误:
/usr/bin/ld: /tmp/ccA9BIT2.o: relocation R_X86_64_32 against `.rodata' can not be used when making a shared object; recompile with -fPIC /tmp/ccA9BIT2.o: error adding symbols: Bad value collect2: error: ld returned 1 exit status
我正在运行ubuntu 16.04和JDK版本8
有什么想法吗?
答案 0 :(得分:1)
如果您开始使用JNI,那么从超简单开始总是好的 - 最好是“Hello world” - 样本。这样,您可以确保链中的所有元素都按预期工作。
从简单的类开始(最好把它放在包中):
package recipeNo001;
public class HelloWorld {
/* This is the native method we want to call */
public static native void displayMessage();
/* Inside static block we will load shared library */
static {
System.loadLibrary("HelloWorld");
}
public static void main(String[] args) {
/* Call to shared library */
HelloWorld.displayMessage();
}
}
您还需要本机代码。尽可能简单
#include <stdio.h>
#include "jni.h"
JNIEXPORT void JNICALL Java_recipeNo001_HelloWorld_displayMessage
(JNIEnv *env, jclass obj) {
printf("Hello world!\n");
}
请注意,JNI在函数名称方面有一个固定的命名约定:Resolving Native Method Names
然后,您可以编译所有内容:
${JAVA_HOME}/bin/javac -d target java/recipeNo001/HelloWorld.java
-d
表示将在目录target
cc -g -shared -fpic -I${JAVA_HOME}/include \
-I${JAVA_HOME}/include/$(ARCH) HelloWorld.c \
-o lib/libHelloWorld.so
编译完所有内容后,您只需运行示例:
${JAVA_HOME}/bin/java \
-Djava.library.path=${LD_LIBRARY_PATH}:./lib \
-cp target recipeNo001.HelloWorld
请注意,我们使用-cp
设置类路径,因为类文件是在target
目录中生成的。
就是这样:)你可以在这里找到更多样本:JNI Cookbook