初试JNI

最近在做Android开发,有必要了解一下JNI,记得core java中有一章专门介绍JNI的,先按照做了一个简单的例子,经典的HelloWorld,呵呵。

 

1. 首先定义一个包含Native方法的类

package com.jyj.test;

public class HelloNative {
    public native static void greeting();

    static {
        System.loadLibrary("HelloNative");
    }
}

 greeting 方法就是一个native的方法,有关键字native进行标示。这里使用了static的方法,也可以是non-static方法。

 

2. 写相应的c function, 下面是定义这个相应c函数的rules:

(1) Use the full Java method name, such as HelloNative.greeting. If the class is in a package, then prepend the package name, such as com.jyj.test.HelloNative.greeting.
(2)Replace every period with an underscore, and append the prefix Java_. For example, Java_HelloNative_greeting or Java_com_horstmann_HelloNative_greeting.
(3)If the class name contains characters that are not ASCII letters or digitsthat is, '_', '$', or Unicode characters with code greater than '\u007F'replace them with _0xxxx, where xxxx is the sequence of four hexadecimal digits of the character's Unicode value.

 

其实这个c函数不必自己写,使用jdk中提供的javah工具就可以生成这个函数的声明:

进入工程中的bin文件夹

javac com.jyj.test.HelloNative.java

javah com.jyj.test.HelloNative

 

在bin文件下下面生成com_jyj_test_HelloNative.h文件,内容为:

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

#ifndef _Included_com_jyj_test_HelloNative
#define _Included_com_jyj_test_HelloNative
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_jyj_test_HelloNative
 * Method:    greeting
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_jyj_test_HelloNative_greeting
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

 函数原型中的JNIEXPORT和JNICALL都在jni.h中定义,相当于JNI的关键字,标示这个函数原型是JNI调用。jni.h可以在jdk中找到

 

3. 下面我们创建HelloNative.c文件,在这里面定义JNICALL Java_com_jyj_test_HelloNative_greeting这个函数,可以将函数原型copy过来:

#include "com_jyj_test_HelloNative.h"
#include <stdio.h>

JNIEXPORT void JNICALL Java_com_jyj_test_HelloNative_greeting(JNIEnv * env, jclass cl) {
	printf("Hello Native World!\n");
}

 OK,到这里编码工作已经结束,下面就是编译链接了

在Linux下面使用gcc:

gcc -fPIC -I jdk/include -I jdk/include/linux -shared -o libHelloNative.so HelloNative.c

 jdk替换未jdk的路径即可。生成了libHelloNative.so这个动态库。

 

若要使用这个动态链接库,我们看到在HelloNative的静态初始化块中有System.loadLibrary(), 调用这个函数可以是JVM加载生成的libHelloNative.so, 这里需要注意的是,虽然库的名字是libHelloNative.so,但在loadLibrary中要使用HelloNatvie。

 

下面看一下HelloNativeTest这个类怎么去调用:

package com.jyj.test;

public class HelloNativeTest {

    public static void main(String [] args) {
        String prop = System.getProperty("java.library.path");
        System.out.println("java.library.path : " + prop);
        HelloNative.greeting();
    }
}
 

 

我们还要JVM知道这个动态库文件的位置,好去加载,通过设置java.library.path就可以了,如

java -Djava.library.path=/home/CORPUSERS/28850439/workspace/ProAndroidAppDev/JNITest/bin com.jyj.test.HelloNativeTest

 

OK,大工告成,运行输出的字符串就是有C函数中的printf输出的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值