一个简单的JNI例子

举个例子,在下面这段代码中,Foo类有一个 native 方法bar

package diveinjvm;
 
public class Foo {
  public native void bar(String s, Object o);
}

我们把文件复制到虚拟机里,这里用的是centos7.4。

然后执行命令:javac -h . Foo.java

可以看到生成了一个 diveinjvm_Foo.h文件

具体文件内容如下:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class diveinjvm_Foo */

#ifndef _Included_diveinjvm_Foo
#define _Included_diveinjvm_Foo
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     diveinjvm_Foo
 * Method:    bar
 * Signature: (Ljava/lang/String;Ljava/lang/Object;)V
 */
JNIEXPORT void JNICALL Java_diveinjvm_Foo_bar
  (JNIEnv *, jobject, jstring, jobject);

#ifdef __cplusplus
}
#endif
#endif

我们来填充这个方法,编写一个foo.c

具体内容如下;

#include <stdio.h>
#include "diveinjvm_Foo.h"
 
JNIEXPORT void JNICALL Java_diveinjvm_Foo_bar__Ljava_lang_String_2Ljava_lang_Object_2(JNIEnv *env, jobject thisObject, jstring str, jobject obj) {
  printf("Hello, World\n");
  return;
}

编译foo.c

gcc -I$JAVA_HOME/include -I$JAVA_HOME/include/linux  -fPIC -shared foo.c -o libfoo.so

我们在Foo.java中调用这个方法

具体代码

package diveinjvm;

public class Foo {
//        public static native void foo();
//        public native void bar(int i, long j);
        public native void bar(String s, Object o);

        int i = 0xDEADBEEF;

        public static void main(String[] args) {
            try {
                System.loadLibrary("foo");
            } catch (UnsatisfiedLinkError e) {
                e.printStackTrace();
                System.exit(1);
            }
            new Foo().bar("", "");
        }
    }

编译: javac diveinjvm/Foo.java

执行结果:

[root@node1 jnidemo]# java diveinjvm.Foo
Hello, World
 

可能遇到的问题:

1.Error: Could not find or load main class diveinjvm.Foo

这里我把Foo.java放到了diveinjvm文件夹下编译的,这个要特别注意

还有一个解决办法 就是 删除package声明 或者 编译的时候 javac Foo.java -d .

这里会自动生成diveinjvm文件夹

2.java.lang.UnsatisfiedLinkError: no foo in java.library.path

这里我们有三种解决方法:

  1. 执行时指定:java -Djava.library.path=/home/jnidemo/libfoo.so diveinjvm.Foo
  2. export LD_LIBRARY_PATH=/home/jnidemo/ 然后执行 java diveinjvm.Foo
  3. 编辑 /etc/profile 文件 在文件末尾添加 export LD_LIBRARY_PATH=/home/jnidemo/ 然后 source /etc/profile
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值