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

来源:互联网 发布:知美术馆门票 编辑:程序博客网 时间:2024/06/05 17:25

欢迎转载!转载时请注明出处: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

 

原创粉丝点击