MyException - 我的异常网
当前位置:我的异常网» C++ » C/C++调用Java代码(属性跟方法)

C/C++调用Java代码(属性跟方法)

www.MyException.Cn  网友分享于:2013-09-24  浏览:10次
C/C++调用Java代码(属性和方法)

back>>

1. JNIEnv对象
     对于本地函数

JNIEXPORT void JNICALL Java_video1_TestNative_sayHello(JNIEnv * env, jobject obj){
    cout<<"Hello Native Test !"<<endl;
}

     JNIEnv类型代表Java环境。通过这个JNIEnv*指针,就可以对Java端的代码进行操作。如,创建Java类得对象,调用Java对象的方法,获取Java对象的属性等。

     JNIEnv的指针会被JNI传送到本地方法的实现函数中来对Java端的代码进行操作
     JNIEnv类中的函数:
     NewObject/NewString/New<TYPE>Array
     Get/Set<TYPE>Field
     Get/SetStatic<TYPE>Field
     Call<TYPE>Method/CallStatic<TYPE>Method

2. Java数据类型与C/C++数据类型的对应关系

Java类型		别名  		本地类型  		字节(bit)
boolean		jboolean	        unsigned char   	8, unsigned
byte      		jbyte		signed char    	8
char      		jchar		        unsigned short    16, unsigned
short		jshort		short    		16
int			jint		        long     		32
long      		jlong		        __int64    	64
float      		jfloat		float    		32
double  		jdouble		double   		64
void      		void		     				n/a  
Object		_jobject	        *jobject

 

3. 获取jclass

    为了能够在C/C++使用Java类,jni.h头文件中专门定义了jclass类型来表示Java中的Class类

    jclass的取得:
    JNIEnv类中有如下几个简单的函数可以取得jclass
    jclass FindClass(const char* clsName)
    jclass GetObjectClass(jobject obj)
    jclass GetSuperClass(jclass obj)
    FindClass 会在classpath系统环境变量下寻找类,需要传入完整的类名,注意包与包之间是用"/"而不是"."来分割
如:jclass cls_string= env->FindClass("java/lang/String");

 

4. 本地代码访问Java类中的属性与方法
    JNI在jni.h头文件中定义了jfieldID,jmethodID类表示Java端的属性和方法
    在访问或设置Java属性的时候,首先就要现在本地代码中取得代表Java属性的jfieldID,然后才能在本地代码中进行Java属性操作。
    同样,在需要调用Java端的方法时,也需要取得代表方法的jmethodID才能进行Java方法调用
    JNIEnv获取相应的fieldID和jmethodID的方法:
    GetFieldID/GetMethodID
    GetStaticFieldID/GetStaticMethodID
    GetMethodID也可以取得构造函数的jmethodID。创建Java对象时调用指定的构造函数。
    如:env->GetMethodID(data_Clazz,"<int>","()V")

 

5. sign签名

    对于 jfieldID GetFieldID(jclass clazz, const char *name, const char *sign)
    clazz代表该属性所在的类,name表示方法名称,sign是签名
    例如TestNative类中有两个重载方法:

package video1;
public class TestNative{
    public void methodTest(int i){
        System.out.println(i);
    }
    public void methodTest(double d){
        System.out.println(d);
    }
}
/*
在C/C++代码中调用其中一个methodTest方法:
首先取得要调用方法所在的类
jclass clazz_TestNative = env->FindClass("video1/TestNative");
//取得jmethodID
jmethodID id_func = env->GetMethodID(clazz_TestNative,"methodTest","");
sign用于指定取得的属性/方法的类型
如果sign指定为(I)V,则取回void methodTest(int)的methodID
如果sign指定为(D)V,则取回void methodTest(double)的methodID
*/

    签名sign

 

用来表示要取得的属性/方法的类型
类型            相应的签名
boolean        Z
byte              B
char              C
short             S
int                  I
long               L
float               F
double           D
void               V
object            L用/分隔包的完整类名:   Ljava/lang/String;
Array             [签名          [I      [Ljava/lang/Object;
Method         (参数1类型签名 参数2类型签名···)返回值类型签名

     使用javap命令来产生签名

     javap -s -p [full class Name]
     -s 表示输出签名信息
     -p 同-private,输出包括private访问权限的成员信息
     例子:

C:\E\java\workspaces\myeclipseblue\JNITest\bin>javap -s -private video1.TestNative
Compiled from "TestNative.java"
public class video1.TestNative extends java.lang.Object{
public java.lang.String name;
  Signature: Ljava/lang/String;
public video1.TestNative();
  Signature: ()V
public int signTest(int, java.util.Date, int[]);
  Signature: (ILjava/util/Date;[I)I
public native void sayHello();
  Signature: ()V
public static void main(java.lang.String[]);
  Signature: ([Ljava/lang/String;)V
} 

6. 本地方法调用Java方法的完整示例:

    - TestNative.java

package video1;

import java.util.Date;

public class TestNative {
	public String name="Test";
	public int number =100;
	public int signTest(int i,Date date,int[] arr){
		System.out.println("Sign Test");
		return 0;
	}
	//native关键字修饰的方法,其内容是C/C++编写的,java中不必为它编写具体的实现
	public native void sayHello();
	public static void main(String[] args) {
		System.loadLibrary("NativeCode");
		TestNative tn = new TestNative();
		tn.sayHello();
	}
}

    - C/C++代码

#include "video1_TestNative.h"
#include <iostream>
using namespace std;
JNIEXPORT void JNICALL Java_video1_TestNative_sayHello(JNIEnv * env, jobject obj){
	cout<<"Hello Native Test !"<<endl;
	//因为test不是静态函数,所以传进来的就是调用这个函数的对象
	//否则就传入一个jclass对象表示native()方法所在的类
	jclass native_clazz = env->GetObjectClass(obj);

	//得到jfieldID
	jfieldID fieldID_prop = env->GetFieldID(native_clazz,"name","Ljava/lang/String;");
	jfieldID fieldID_num = env->GetFieldID(native_clazz,"number","I");

	//得到jmethodID
	jmethodID methodID_func=env->GetMethodID(native_clazz,"signTest","(ILjava/util/Date;[I)I");
	//调用signTest方法
	env->CallIntMethod(obj,methodID_func,1L,NULL,NULL);

	//得到name属性
	jobject name = env->GetObjectField(obj,fieldID_name);
	//得到number属性
	jint number= env->GetIntField(obj,fieldID_num); 

	cout<<number<<endl;//100
	//修改number属性的值
	env->SetIntField(obj,fieldID_num,18880L);  
	number= env->GetIntField(obj,fieldID_num);  
	cout<<number<<endl;//18880
 }

    图解签名:

    - 编译source.cpp,执行TestNative.java类。

 

 

文章评论

要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
Java程序员必看电影
Java程序员必看电影
每天工作4小时的程序员
每天工作4小时的程序员
鲜为人知的编程真相
鲜为人知的编程真相
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
总结2014中国互联网十大段子
总结2014中国互联网十大段子
代码女神横空出世
代码女神横空出世
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
程序员必看的十大电影
程序员必看的十大电影
老程序员的下场
老程序员的下场
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
编程语言是女人
编程语言是女人
 程序员的样子
程序员的样子
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
10个调试和排错的小建议
10个调试和排错的小建议
我的丈夫是个程序员
我的丈夫是个程序员
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
程序员应该关注的一些事儿
程序员应该关注的一些事儿
一个程序员的时间管理
一个程序员的时间管理
我是如何打败拖延症的
我是如何打败拖延症的
漫画:程序员的工作
漫画:程序员的工作
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
为什么程序员都是夜猫子
为什么程序员都是夜猫子
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
如何成为一名黑客
如何成为一名黑客
程序员的鄙视链
程序员的鄙视链
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
程序员都该阅读的书
程序员都该阅读的书
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有