Cocos2d-x初入学堂(16)-->C++通过JNI和Java的数据相互

欢迎转载!转载时请注明出处:http://write.blog.csdn.net/postedit/8182856

有一周多没有更新博客了,估计很多人都在心里问,博主最近在干吗啦!都没有到发表新的博文了,由于上上周的时候,出去失业状态,然后再群里自荐,然后就有朋友给我推荐了工作,不记得具体是那个了,在此感谢他,也感谢那么多的朋友们给我的肯定...非常感谢!

JNI估计大部分朋友听到这个东西就会怕~ 如果没有接触过,却是搞的你非常的头大...好了废话不多说了...开始吧

首先来接触一些知识点:

1、基本数据类型对应该关系表:

其实仔细看看发现就是对应java类型的首字母拉, Boolean比较特殊, 对应的是 Z Long 对应J

2、Java 方法映射到C中的签名:(介绍四个方法对应的签名)

public void test(){} ()V

public void test1(int i){} (I)V

public int test2(){ return 1;} ()I

public int test3(int i) { return i;} (I)I

3、引用数据类型:比较麻烦点,以“L”开头,以“;”结束,中间对应的是该类型的路径

如:String : Ljava/lang/String

Object: Ljava/lang/Object

自定义类 Cat 对应 package com.duicky;

Cat:Lcom/duicky/Cat;

4、数组表示: 数组表示的时候以“[” 为标志,一个“[”表示一维数组

如:int [] :[I

Long[][] : [[J

Object[][][]:[[[Ljava/lang/Object;

5、查看JDK生成的签名写一个测试类,有如下方法:

public void test(){}
public void test1(int i){}
public int test2(){ return 1;}
public int test3(int i) { return i;}
public Cat test4(Cat c){ return new Cat();}
public Object test5(int [] a){ return null;}
public int[][] test5(long [][] b){ return null;}
public void test6(Object[][][] b){}


打开Cmd 命令行,cd 到 生成测试类打开Cmd 命令行,cd 到 生成测试类 的 Class 目录:

Cd 到相对应的 文件夹

输入命令: javap –s 加上你要查看方法签名的类 名

如: javap –s Test 结果就显示出我们想要的签名了

6、Java调用C方法:

第一步:编写native方法:

private native int fromC();

第二步:编写JNI:(我是直接用的cocos2dx中的main.cpp方法,然后写到extern"C"{}中的喔~ 为了易看,其他代码省略)

using namespace cocos2d;
using namespace cocos2d::extension;
using namespace std;

extern "C"
{

jint Java_potter_back_MyHelloWorld_fromC(){
	return 222;
}

第三步:调用native方法

package potter.back;

public class Main {

	public static void main(String[] args) {
		System.out.println("fromC++"+new Main().fromC());
	}
	private native int fromC();
}


7、C调用Java方法:后面这样放着好看点,就用后面这种方式排版吧~

调用JNI方法
package potter.back;

public class Main {

	public static void main(String[] args) {
		new Main().fromJava();
	}
	private native int fromJava();
}

class Potter {
	
	public void fromJava(String msg){
		System.out.println("From Android");
	}
	
}


编写JNI方法

void Java_potter_back_MyHelloWorld_fromJava(JNIEnv* jniEnv, jobject thiz)
{
	//映射类
	jclass Potter=jniEnv->FindClass("potter/back/Potter");
	//映射构造方法
  	jmethodID construction_id = jniEnv->GetMethodID(Potter,"<init>", "()V");
  	//创建对象
  	jobject mPotter = jniEnv->NewObject(obj_class,construction_id);
  	//映射对象方法
	jmethodID fromJava=jniEnv->GetMethodID(Potter,"fromJava","(Ljava/lang/String;)V");
	//调用Java对象mPotter的fromJava方法
	jniEnv->CallVoidMethod(mPotter, fromJava,jstrMSG);
}


8、通过JNI传递Java对象:

第一步:
public class Main {

	public static void main(String[] args) {
		new Main().javaObjectToC();
	}
	public void javaObjectToC(){
		//通过C++调用Java中的方法,然后传递Person对象
		Person p=new Person(24);
		cCallJava(p);
		System.out.println("p's age="+p.age);
	}
	public native void cCallJava(Person p);
}

class Person{
	public int age;
	
	public Person(int age){
		this.age=age;
	}
	
	public void walk(){
		System.out.println("Person can walk");
	}
}


第二步:

void Java_potter_back_MyHelloWorld_fromJava(JNIEnv* jniEnv, jobject thiz,jobject obj)
{
	//获得Person类:获得obj对象的句柄
	jclass cls =jniEnv->GetObjectClass(obj);

	jfieldID fid = jniEnv->GetFieldID(cls,"age", "I");
	jmethodID mid = jniEnv->GetMethodID(cls, "walk", "()V");
	int value = jniEnv->GetIntField(obj, fid);

	jniEnv->SetIntField(obj, fid, 6);
	jniEnv->CallVoidMethod(obj, mid);
}


第三步:运行

Person can walk

p's age=6 //此值被修改了喔~ 出事为24,然后再JNI中设置成6了喔

9、Java通过JNI传递C++对象:(这种方法,我找了n多的资料,都没有找到对应的,不过利用7小标题,这种方式是可以进行数据传输的) 如果有朋友知道有更加直接的办法请告诉我...万分感谢~

感谢大家阅览我的博文,希望也能看到大家留下的脚印...呵呵!
如果讲述得有误,或者不对的地方,还望各位指出!

参考资料:http://www.cnblogs.com/luxiaofeng54/archive/2011/08/18/2143977.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值