JNI教程(所用的环境为LINUX)

1.什么是JNI

JNIJavaNative Interface的缩写,它提供了若干的API实现了Java和其他语言的通信(主要是C&C++),通俗来说就是Java语言调用其他语言提供的接口。

 

2.什么是native方法

简单地讲,一个Native Method就是一个java调用非java代码的接口。一个NativeMethod是这样一个java的方法:该方法的实现由非java语言实现,比如C。这个特征并非java所特有,很多其它的编程语言都有这一机制,比如在C++中,你可以用extern "C"告知C++编译器去调用一个C的函数。

 

3.实例

1)创建一个TestJni.java的文件

import java.util.*;

 

public class TestJni

{

      //声明原生函数:参数为String类型

public native void print(String content);

     

      //加载本地库代码  

      static

      {

           System.loadLibrary("TestJni");

      }

}

 

注意print方法的声明,关键字native表明该方法的具体实现是在其他语言中(c&c++)实现的

另外注意static代码段的System.loadLibrary调用,这段代码表示在程序加载的时候,自动加载libTestJni.so库。

 

编译 TestJni.java文件:javac TestJni.java

在当前文件夹下生成TestJni.class文件

 

2)生成TestJni.h文件

执行命令:javah  -jni  TestJni

/* DO NOT EDIT THIS FILE - it is machine generated */

#include <jni.h>

/* Header for class TestJni */

 

#ifndef _Included_TestJni

 

#define _Included_TestJni

#ifdef __cplusplus

extern "C" {

#endif

/*

 * Class:     TestJni

 * Method:    print

 * Signature: (Ljava/lang/String;)V

 */

JNIEXPORT void JNICALL Java_TestJni_print

  (JNIEnv *, jobject, jstring);

 

#ifdef __cplusplus

}

#endif

#endif

 

该文件中包含了一个函数Java_TestJni_print的声明。这里面自动包含两个非常重要的参数:JNIEnv*jobject

 

3)创建TestJni.C文件

#include <jni.h>

#include <stdio.h>

#include <TestJni.h>

 

JNIEXPORT void JNICALL Java_TestJni_print(JNIEnv *env,jobject obj, jstring content)

{

      // instring字符串取得指向字符串 UTF编码的指针

      //注意C语言必须(*env)->         C++ env->

      const jbyte *str =(const jbyte *)(*env)->GetStringUTFChars(env,content, JNI_FALSE);

      

      printf("Hello---->%s\n",str);

 

      // 通知虚拟机本地代码不再需要通过 str访问 Java字符串。

     (*env)->ReleaseStringUTFChars(env, content, (const char *)str );

 

    return;

}

//jobject指向在此Java代码中实例化的 Java对象 LocalFunction的一个句柄,相当于 this指针

参数类型 jstring对应java中的String,这里是有所不同的。每一个Java里的类型这里有对应的与之匹配。

 

4)生成共享库

命令行输入:gcc-I/usr/lib/jvm/java-6-sun/include/linux/  -I/usr/lib/jvm/java-6-sun/include/   -fPIC  -shared -o libTestJni.so TestJni.c

执行完命令后会在当前目录生成liblibTestJni.so库文件,其功能就是有一个print函数与刚才所创建的TestJni.java文件对应,

TestJni.java类中加载库liblibTestJni.so,声明了其函数print,所以TestJni.java中具备使用print函数的功能

注意:

其中的选项-I/usr/lib/jvm/java-6-sun/include/linux/  -I/usr/lib/jvm/java-6-sun/include/   是Java的include目录(请根据自己系统环境设定)

Linux下一个库的必须要是:lib+库名+.so。链接的时候只需要提供库名就可以了

 

5)创建HelloWorld.java文件

import java.util.*;

public class HelloWorld

{

     public static void main(String argv[])

     {

         TestJni demon = new TestJni();

         Demon.print(“world!”);

     }

 

}

输入命令编译: javac HelloWorld.java,生成HelloWorld.class


6)运行

命令行输入:Java HelloWorld

 

 

4.JNI的副作用

一旦使用JNIJAVA程序就丧失了JAVA平台的两个优点:

1、程序不再跨平台。要想跨平台,必须在不同的系统环境下重新编译本地语言部分。

2、程序不再是绝对安全的,本地代码的不当使用可能导致整个程序崩溃。一个通用规则是,你应该让本地方法集中在少数几个类当中。这样就降低了JAVAC之间的耦合性。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值