当前位置:编程学习 > JAVA >>

JAVA之JNI小结

JNI 是 Java Native Interface 的缩写。 Java™ 本机接口(Java Native Interface,JNI)是一个标准的 Java API,它支持将 Java 代码与使用其他编程语言编写的代码相集成。如果您希望利用已有的代码资源,那么可以使用 JNI 作为您工具包中的关键组件 —— 比如在面向服务架构(SOA)和基于云的系统中。
 
1、在JDK目录下的javah.exe就是可以将Java代码转化成C++代码的头文件。(注意完整类名与文件路径)
2、将生成的头文件复制到C++工程下,(注意:JDK目录下的include头文件也需要相应的包含到工程里面), 按照生成的函数声明来写函数实现就可以了。在cpp文件中要include这个文件。
#include <jni.h>这种是在系统目录下去找,自己复制进去的需要改成双引号#include "jni.h"。
3、编译好工程之后,就会生成dll文件了。(dll文件和exe一样,  是可执行的二进制代码)
 
4、生成dll后,就将其加到环境变量,方便调用。如在Java中System.loadLibrary("aaa")可调用aaa.dll
Eclipse在每次启动的时候会读取一次环境变量,更改环境变量之后需要重启eclipse。
 
Java中类型与C/C++中对应关系
 
Java中的类的对应
 
Sign签名, 用来识别对应各个方法。
JDK下的javap.exe能输出签名。用法javap -s -p 完整类名
 
 
全局引用/局部引用/弱全局引用:
弱全局引用不会阻止垃圾回收器回收这个引用所指的对象。因此弱全局引用所引用的对象不一定存在。所以有必要先判断。
 
Java中多态与C++中的Virtual对应关系(父类与子类的调用):
Java中类的成员方法都是虚拟的。CallNonvirtualVoidMethod()方法来调用。
 
一个简单的例子:
Java端代码:
[java]  
package com.jni;  
  
import java.util.Date;  
  
/* 
 * 2. 本地代码C++访问Java中的类与方法等. 在dll中改变了property的值, 调用了他的方法. 
 */  
public class NativeAccessJava  
{  
    //本地方法声明  
    public native void nativeAccessJavaMethod();  
      
    //Java中的属性  
    public int property=10;  
  
    //Java中的方法  
    public int function(int a, Date date, int[] b)  
    {  
        System.out.println("Native C code access Java Class!");  
        return 0;  
    }  
      
    //在C代码中调用这个方法  
    public double maxValue(double a,double b)  
    {  
        return a>b?a:b;  
    }  
      
    //关于多态与C++中virtual函数的对应  
    public Father inst = new Son();  
      
      
    public static void main(String[] args)  
    {  
        NativeAccessJava nativeAccessJava = new NativeAccessJava();  
        System.out.println("改变前的值是: "+nativeAccessJava.property);  
  
        System.setProperty("java.library.path", ".");//这里就是在改临时环境变量  
        System.loadLibrary("NativeAccessObject");//jin.dll, 为了方便, 可以将动态链接库直接设置到环境变量里面  
          
        //改变值的函数是在nativeAccessJavaMethod()中写着的, 所以要先嗲用这个方法之后, 值才改变的  
        nativeAccessJava.nativeAccessJavaMethod();  
        System.out.println("改变后的值是: "+nativeAccessJava.property);  
    }  
}  
 
C++端代码:
[cpp]  
/* DO NOT EDIT THIS FILE - it is machine generated */  
#include "jni.h"  
/* Header for class com_jni_NativeAccessJava */  
  
#ifndef _Included_com_jni_NativeAccessJava  
#define _Included_com_jni_NativeAccessJava  
#ifdef __cplusplus  
extern "C" {  
#endif  
/* 
 * Class:     com_jni_NativeAccessJava 
 * Method:    nativeAccessJavaMethod 
 * Signature: ()V 
 */  
JNIEXPORT void JNICALL Java_com_jni_NativeAccessJava_nativeAccessJavaMethod  
  (JNIEnv *, jobject);  
  
#ifdef __cplusplus  
}  
#endif  
#endif  
 
[cpp]  
#include "com_jni_NativeAccessJava.h"  
#include "windows.h"  
#include <iostream>  
#include <algorithm>  
using namespace std;  
  
/************************************************************************/  
/* 2. 本地C代码调用Java中的类.                                             */  
/************************************************************************/  
JNIEXPORT void JNICALL Java_com_jni_NativeAccessJava_nativeAccessJavaMethod(JNIEnv *env, jobject obj)  
{  
    jclass java_class = env->GetObjectClass(obj);//get class object  
    jfieldID fieldID_prop = env->GetFieldID(java_class,"property","I");//get property id  
    jmethodID methodID_func = env->GetMethodID(java_class,"function","(ILjava/util/Date;[I)I");//get method id e.g.  
  
    //取得Java类中属性property的值  
    jint number = env->GetIntField(obj,fieldID_prop);  
    cout << number<<endl; //输出取得的值, 并输出. 这个在Java调用的时候会输出.  
  
    //修改property的值, 改为120  
    env->SetIntField(obj,fieldID_prop,120L);  
  
    //调用java中的方法  
    jmethodID methodID_max = env->GetMethodID(java_class,"maxValue","(DD)D");//get method ID  
    jdouble maxValue = env->CallDoubleMethod(obj,methodID_max,3.11,3.15);  
    cout<< "the maxValue is "<<maxValue<<endl;  
  
    //调用java继承关系的类, 调用的是子类的func方法. 相当于Father p = nativeAccessJava.p;  p.func();  
    jfieldID id_inst = env->GetFieldID(java_class,"inst","Lcom/jni/Father;");  
    jobject inst = en
补充:软件开发 , Java ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,