我是java的新手,当前正在学习本机方法,当我创建以下文件时:
Main.java :
public class Main {
public native int intMethod(int i);
public static void main(String[] args) {
System.loadLibrary("Main");
System.out.println(new Main().intMethod(2));
}
}
MAIN.C :
#include <jni.h>
#include "Main.h"
JNIEXPORT jint JNICALL Java_Main_intMethod(
JNIEnv *env, jobject obj, jint i) {
return i * i;
}
编译并运行:
javac Main.java
javah -jni Main
gcc -shared -fpic -o libMain.so -I${JAVA_HOME}/include \
-I${JAVA_HOME}/include/linux Main.c
java -Djava.library.path=. Main
输出:
4
但是,当我这样做时:
troller.java :
public class troller {
public native int intMethod(int i);
public static void main(String[] args) {
System.loadLibrary("troller");
System.out.println(new troller().intMethod(2));
}
}
troller.c :
#include <jni.h>
#include "troller.h"
JNIEXPORT jint JNICALL Java_Main_intMethod(
JNIEnv *env, jobject obj, jint i) {
return i * i;
}
编译并运行:
javac troller.java
javah -jni troller
gcc -shared -fpic -o libMain.so -I${JAVA_HOME}/include \
-I${JAVA_HOME}/include/linux Main.c
java -Djava.library.path=. troller
输出:
Exception in thread "main" java.lang.UnsatisfiedLinkError: no troller in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1886)
at java.lang.Runtime.loadLibrary0(Runtime.java:849)
at java.lang.System.loadLibrary(System.java:1088)
at troller.main(troller.java:4)
如果我更改名称,为什么程序会停止工作?
编辑: 在查看答案后,我发现了某些不一致的情况,现在重新创建了所有文件,但错误仍然存在: 的 Native.java
public class Native{
public native int intMethod(int i);
public static void main(String[] args){S
System.loadLibrary("Native");
System.out.println("In java... :)");
System.out.println(new Native().intMethod(4));
}
}
Native.c
#include<jni.h>
#include"Native.h"
JNIEXPORT jint JNICALL Java_Native_intMethod(
JNIEnv *env, jobject obj, jint i){
printf("In C .... :)");
return i*i;
}
编译并运行
javac Native.java
javah -jni Native
gcc -shared -fpic -o libMain.so -I${JAVA_HOME}/include \
-I${JAVA_HOME}/include/linux Native.c
java -Djava.library.path=. Native
Exception in thread "main" java.lang.UnsatisfiedLinkError: no Native in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1886)
at java.lang.Runtime.loadLibrary0(Runtime.java:849)
at java.lang.System.loadLibrary(System.java:1088)
at Native.main(Native.java:4)
答案 0 :(得分:3)
使用.h
为本机方法生成javah
存根时,它包含类的包和类名。这样您就可以在不同的类中使用相同的方法名称。
Java_Main_intMethod
需要重命名为
Java_troller_intMethod
如果类相同但包更改,则还必须更改方法名称。
注意:C
没有@Override
,您可以实现未在.h
文件中声明的方法。 ;)
答案 1 :(得分:1)
如果要将Main重命名为Troller,则需要始终如一地执行此操作。但是您的本机库仍称为libMain.so。因此,当您尝试加载库控制器时,它会失败,因为这是错误的名称。
由于您的C文件现在名为troller.c,因此您的gcc命令应该不起作用,或者您正在编译错误的文件。
答案 2 :(得分:0)
我还没有使用Java的原生方法,并试图猜测可能是什么问题。 在第二个遵守和运行命令
-I $ {JAVA_HOME} / include / linux Main.c
看起来应该有troller.c而不是Main.c