手机版
你好,游客 登录 注册 搜索
背景:
阅读新闻

JNI调用的helloworld(JNI_OnLoad映射方式)

[日期:2017-03-07] 来源:Linux社区  作者:thestrals [字体: ]

本示例展示JNI的基本示例,helloworld级别的,不过是用JNI_OnLoad映射的方式。直接看代码,先看包含native method的Person.java的代码:

package helloworld;

/**
 * author : Zhou Shenshen
 * date  : 2016.7.16
 * desc  : It is a class to show how to use JNI.
 *          演示调用JNI本地方法的写法和加载动态库
 * email  : zhouss@iPanel.cn
 */
public class Person{

    /* Load the shared library libperson.so 加载C语言编写的动态库*/
    static{
        String classDir = Person.class.getResource("/").getPath();
        System.load(classDir + "helloworld/libperson.so");
    }

    /* Two native implemented by person.c 两个native method通过person.c来实现 */
    public native void show();
    public native void say(String content);
}

这里native method的定义不用多说,注意就是调用System的load时,传入的参数是库的全名,linux下包括lib和.so,而loadLibrary方法则是传入库的名字,没有前后缀。这里采用绝对路径定位和加载库,不用在设定库的参数。

接下来看person.c的代码:

#include <jni.h>
#include <stdio.h>

/* Declare two function map to java native method 声明映射过来的本地函数 */
void native_show(JNIEnv * env,jobject obj);
void native_say(JNIEnv * env,jobject obj,jstring string);

/* The array to map java method and c function 映射用的JNINativeMethod数组 */
static JNINativeMethod methods[] = {
    {"show","()V",(void *)native_show},
    {"say","(Ljava/lang/String;)V",(void *)native_say}
};

/* This function will be exec when libperson.so been loading. */
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved){
    JNIEnv * env = NULL;
    jclass cls = NULL;
    jint result = -1;
    if((*vm)->GetEnv(vm,(void **)&env,JNI_VERSION_1_6) != JNI_OK){
        printf("err!!");
        return JNI_ERR;
    }
    cls = (*env)->FindClass(env,"helloworld/Person");  //通过类路径字符串找到对应类
    (*env)->RegisterNatives(env,cls,methods,sizeof(methods)/sizeof(JNINativeMethod));//调用RegisterNatives来注册本地方法,完成映射
    return JNI_VERSION_1_6;
}

/* Define the c native function. 本地方法映射过来的实现*/
void native_show(JNIEnv * env,jobject obj){
    printf("hello!!\n");
}
void native_say(JNIEnv * env,jobject obj,jstring string){
    const char * str = (*env)->GetStringUTFChars(env,string,0); //将jstring转成c语言中的字符串。
    printf("content : %s\n",str);
}

然后写个主函数测试JNI调用的情况:

package helloworld;
/**
 * author : Zhou Shenshen
 * date  : 2016.7.16
 * desc  : As the entrance for the example.
 * email  : zhouss@iPanel.cn
 */
public class Main{
    public static void main(String[] args){
        Person p = new Person();
        p.show();
        p.say("I am XiaoMing!");
    }
}

编译运行的脚本如下:

#!/bin/sh

#test the libperson.so is exist.
if [ -e libperson.so ];then
  #change to .. directory to run this example
  cd ..
  java  helloworld.Main
  exit 0;
fi

#Compiler *.java to *.class
javac Person.java Main.java
#Test the JAVA_HOME
if [ $JAVA_HOME != ""  ]; then
  #Compiler *.c to *.o,then link to shared library *.so.
  gcc -fPIC -c -I$(echo $JAVA_HOME)/include/ -I$(echo $JAVA_HOME)/include/linux person.c
  gcc -shared -o libperson.so person.o
  #change to .. directory to run this example
  cd ..
  java helloworld.Main
  exit 0
else
  echo "JAVA_HOME is empty variable"
  exit 1
fi

  linux下bash下运行的结果如下:

hello!!
content : I am XiaoMing!

更多Android相关信息见Android 专题页面 http://www.linuxidc.com/topicnews.aspx?tid=11

本文永久更新链接地址http://www.linuxidc.com/Linux/2017-03/141467.htm

linux
本文评论   查看全部评论 (0)
表情: 表情 姓名: 字数

       

评论声明
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事或刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款