使用java的本机方法

时间:2015-09-22 18:34:08

标签: java

我是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)

3 个答案:

答案 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