Java JNI简单实现(C和JAVA互调)

一、JNI简述
          http://baike.baidu.com/view/1272329.htm,真心懒了-_-!
 
二、JNI基本类型
         copy表一份,很详细的了!
Java类型
本地类型
描述
boolean
jboolean
C/C++8位整型
byte
jbyte
C/C++带符号的8位整型
char
jchar
C/C++无符号的16位整型
short
jshort
C/C++带符号的16位整型
int
jint
C/C++带符号的32位整型
long
jlong
C/C++带符号的64位整型
float
jfloat
C/C++32位浮点型
double
jdouble
C/C++64位浮点型
Object
jobject
任何Java对象,或者没有对应java类型的对象
Class
jclass
Class对象
String
jstring
字符串对象
Object[]
jobjectArray
任何对象的数组
boolean[]
jbooleanArray
布尔型数组
byte[]
jbyteArray
比特型数组
char[]
jcharArray
字符型数组
short[]
jshortArray
短整型数组
int[]
jintArray
整型数组
long[]
jlongArray
长整型数组
float[]
jfloatArray
浮点型数组
double[]
jdoubleArray
双浮点型数组
表2 Java类型映射
 
三、Java调用C&C++
1)Java类中编写native声明的方法。
     2)javah命令生成JNI样式.h文件。
     需要注意以下几点:1、JNI调用函数必须要用C编译器编译。也就是C++别忘了extern "C"那块;2、方法名格式:Java_pacakege_class_method。
 
例子程序的HelloJni.h文件:
 
#ifndef HELLOJNI_H_ 
#define HELLOJNI_H_ 
 
#include <jni.h> 
 
// JNI调用函数必须要用C编译器编译 
// C++不加extern "C",调用会有异常 
#ifdef __cplusplus 
extern "C" { 
#endif 
 
/* 
 * 1、JNIEXPORT、JNICALL:jni的宏 
 * 2、jstring:返回值类型(对应java的string) 
 * 3、C方法名:Java_pacakege_class_method 
 * 4、JNIEnv*、jobject:jni必要参数(jni环境、java对象) 
 */ 
JNIEXPORT void JNICALL Java_org_join_jni_JniTest_sayHelloWin (JNIEnv*, jobject, int, int, int, int); 
 
#ifdef __cplusplus 
} 
#endif 
 
#endif /* HELLOJNI_H_ */ 
3)用C&C++方法实现本地方法,编译成动态库
4)Java类中用System.loadLibrary()或System.load()方法加载生成的dll文件
System.loadLibrary():装载Windows\System32下或 jre\bin或 Tomcat\bin目录下的本地链接库
System.load():根据具体的目录来加截本地链接库,必须是绝对路径
5)OK!
注意jni方法的使用,C&C++格式是不一样的,如下:
C 格式:(*env) -> <jni function> (env, <parameters>)

返回jstring:return (*env)->NewStringUTF(env, "XXX");

C++ 格式:env -> <jni function> (<parameters>)
返回jstring:return env->NewStringUTF("XXX");
另外数组类型的话,jni提供了操作的函数,稍复杂点,例子里没写也就不说了。
 
四、C&C++回调Java
直接看代码吧,每步都有注释了。
  1)包org.join.jni下类JniTest内定义的两方法
/** C回调Java方法(静态) */ 
public static int add(int x, int y) { 
System.out.println("==Java静态add方法=="); 
return x + y; 
} 
 
/** C回调Java方法(非静态) */ 
public int sub(int x, int y) { 
System.out.println("==Java非静态sub方法=="); 
return x - y; 
} 
2)CallJava.h
#ifndef CALLJAVA_H_ 
#define CALLJAVA_H_ 
 
#include <jni.h> 
#include <stdio.h> 
#include <stdlib.h> 
 
int add(JNIEnv*, int, int); 
int sub(JNIEnv*, int, int); 
 
jobject getInstance(JNIEnv*, jclass); 
 
#endif /* CALLJAVA_H_ */ 
3)CallJava.cpp
#include "CallJava.h" 
 
/** 
 * C回调Java方法(静态) 
 */ 
int add(JNIEnv *env, int x, int y) { 
    // 获取类 
    jclass AnalyzeCidUtil = env->FindClass("org/join/jni/JniTest"); 
    if (NULL == AnalyzeCidUtil) { 
        return -1; 
    } 
 
    // 获取类add静态方法 
    /* 
     * 第三个参数为方法签名 
     * 
     * 可用JDK自带工具javap生成该类所有方法签名 
     * 控制台进入该类class文件目录,输入:javap -s -private 类名 
     */ 
    jmethodID add = env->GetStaticMethodID(AnalyzeCidUtil, "add", "(II)I"); 
    if (NULL == sub) { 
        env->DeleteLocalRef(AnalyzeCidUtil); // 删除类指引 
        return -2; 
    } 
 
    // 调用静态int方法 
    int result = env->CallStaticIntMethod(AnalyzeCidUtil, add, x, y); 
 
    // 返回结果 
    return result; 
} 
 
/** 
 * C回调Java方法(非静态) 
 */ 
int sub(JNIEnv *env, int x, int y) { 
    // 获取类 
    jclass AnalyzeCidUtil = env->FindClass("org/join/jni/JniTest"); 
    if (NULL == AnalyzeCidUtil) { 
        return -1; 
    } 
 
    // 实例化类对象 
    jobject mAnalyzeCidUtil = getInstance(env, AnalyzeCidUtil); 
    if (NULL == mAnalyzeCidUtil) { 
        env->DeleteLocalRef(AnalyzeCidUtil); // 删除类指引 
        return -2; 
    } 
 
    // 获取对象sub方法 
    jmethodID sub = env->GetMethodID(AnalyzeCidUtil, "sub", "(II)I"); 
    if (NULL == sub) { 
        env->DeleteLocalRef(AnalyzeCidUtil); // 删除类指引 
        env->DeleteLocalRef(mAnalyzeCidUtil); // 删除类对象指引 
        return -3; 
    } 
 
    // 调用非静态int方法 
    int result = env->CallIntMethod(mAnalyzeCidUtil, sub, x, y); 
 
    // 返回结果 
    return result; 
} 
 
/** 
 * 实例化类对象 
 */ 
jobject getInstance(JNIEnv *env, jclass clazz) { 
    // 获取构造方法 
    jmethodID constructor = env->GetMethodID(clazz, "<init>", "()V"); 
    if (NULL == constructor) { 
        return NULL; 
    } 
    // 实例化类对象 
    return env->NewObject(clazz, constructor); 
} 
注意静态和非静态方法相差的实例化类对象的区别!
 


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值