`

让C++和Java相互调用(2)

 
阅读更多
http://chnic.iteye.com/blog/236248



3.getRamdomOrder()



这个方法会从backend得到一个随机的Order对象(抱歉这里“Random”拼错了),然后再调用java中相应的通知方法来通知foreground。getRamdomOrder方法没有参数,但是所对应的C++方法里却有两个参数,一定有人会不解。其实细心的朋友一定会发现,JNI里所有对应Java方法的C++ 方法都会比Java方法多两个参数,第一个参数是我们很熟悉的JNIEnv*指针,第二个参数有时是jobject有时是个jclass。针对这第二个参数在这里有必要多废话两句。



其实第二个参数传递的是包含了native本地方法的对象或者类对象,我们知道非静态的方法是属于某一个对象的,而静态方法是属于类对象的,所以静态方法可以被所有对象共享。有这个对象/类对象,我们就可以很方便的操作包含了native方法的对象的一些函数了。(这句话有点绕口,没看明白的建议多读两遍)。



废话完了言归正传,因为getRamdomOrder不是静态的,所以C++相对应的参数中传递来的是一个jobject对象。



Cpp代码 
jclass business_class = env->GetObjectClass(obj); 

jclass business_class = env->GetObjectClass(obj);

这一句不难理解,GetObjectClass方法可以得到一个对象的类对象,这句有点像Java中的Object.class。不熟悉的朋友建议再去看一下Java反射机制。接下来的几句C++代码应该在之前的方法1和方法2中都解释过。早backend端会发一个“消息”给foreground,之后new一个新的Order类出来。接下来的三句有必要再废话一下。



Cpp代码 
jfieldID amount_field = env->GetFieldID(order_class, "amount", "I");  
jint amount = env->GetIntField(order, amount_field);  
cout << "amount: " << amount << endl; 

jfieldID amount_field = env->GetFieldID(order_class, "amount", "I");
jint amount = env->GetIntField(order, amount_field);
cout << "amount: " << amount << endl;

之前我为Order这个Javabean的amount的属性设置了一个初始值为30,其实就是为了在这里演示如何在C++中拿一个Java对象的属性,拿的方法和我们之前说过的调用Java方法的程序差不多,也要先拿到一个jfieldID,之后调用Get<type>Field方法来取得某一个对象中的某一个属性的数值,最后cout把他打印出来。我们编写测试代码来看一下最终效果。



Java代码 
Business b = new Business();                   
Order o2 = b.getRamdomOrder();  
System.out.println(o2.getName()); 

Business b = new Business();
Order o2 = b.getRamdomOrder();
System.out.println(o2.getName());

运行上述的测试代码之后,控制台上打出了



Got a notification.
amount: 30
Fruit



和我们想要的结果是一样的,测试成功。



4.analyzeOrder(Order order)



这是一个静态方法,foreground会通过这个方法传一个Order的对象到backend去,然后再由CPP端进行“analyze”。在这里我们取出来传递过来的Order对象的name属性,然后打印到控制台上。因为这个方法是静态static方法,所以相对应的C++方法中的第二个参数也变成了jclass对象,也就是Business.class这个类对象。第三个参数是一个jobject对象,很明显就是我们传递过来的order对象。



前5句代码应该不难理解,就是调用getName这个方法,然后打印出来。因为JNI的API中并没有提供CallStringMethod这个方法,所以我们用CallObjectMethod这个方法来取得name这个字符串(String很明显也是一个Object),然后再转型成为jstring。也就是下面这句代码。



Cpp代码 
jstring name_str = static_cast<jstring>(env->CallObjectMethod(obj, getName_method)); 

jstring name_str = static_cast<jstring>(env->CallObjectMethod(obj, getName_method)); 
取到了name这个字符串之后cout打印出来,之后调用Business这个类对象中的静态方法notificationByStatic来通知foreground。调用的流程以及方法和非静态都是一样的,只不过注意JNI中调用静态方法的API所传递的一个参数是一个jclass而非jobject(这个也不难理解,因为静态方法是属于class类对象的)



还是编写测试代码测试这个方法



Java代码 
Business b = new Business();          
Order o = b.getOrder("Watermelom", 100);  
Business.analyzeOrder(o); 

Business b = new Business();
Order o = b.getOrder("Watermelom", 100);
Business.analyzeOrder(o); 
控制台上打印出



Name in Java_com_chnic_service_Business_analyzeOrder: Watermelom
Got a notification in a static method.



第一句是C++中cout打印出来的,第二句则是Java中的静态方法打印出来的,和我们想要的结果是一致的。





呼~好不容易介绍完了4个方法,最后总结一下吧。



JNI中所提供的API远远不止这4个方法中所使用的API。上面介绍的都是比较常用的,本人也不可能罗列出所有的API。
了解了JNI编程更加有利于深入了解Java中的反射机制,反之亦然。


因此如果有对JNI编程有兴趣或者有更深入的需要,可以参考一下sun的相关文档。在这里上传sun提供的JNI的API手册,还有上面例子中所用的演示代码给大家参考。

分享到:
评论

相关推荐

    JNI编程(二) —— 让C++和Java相互调用(2)

    在本篇关于JNI编程的第二部分中,我们将深入探讨如何让C++与Java实现互相调用,从而增强应用程序的功能和性能。这通常涉及到在Java程序中调用本地方法(即C++函数)以及在本地代码中调用Java方法。 首先,了解JNI的...

    用JNI实现java和C++的相互调用

    下面我们将详细介绍如何用JNI实现Java和C++的相互调用。 首先,我们有一个名为`JniTest`的Java类,它包含多个native方法,这些方法将在C++中实现。例如,`PrintHello()`、`Print()`、`AccessField()`、`...

    JNI实现C/C++与Android/JAVA相互调用

    Android JNI/NDK开发(2)JNI实现C/C++与Android/JAVA相互调用 http://blog.csdn.net/u014702653/article/details/71141423

    Java和c++相互调用javalearnsa资料分享

    2. **JNI函数接口**:JNI提供了一系列的C/C++函数接口,如`JNIEnv`指针,它是访问Java对象和执行Java方法的关键。`JNIEnv`包含了各种函数指针,可以用来创建和操作Java对象,调用Java方法,抛出异常等。 3. **Java...

    通过JNI实现C++与JAVA相互调用之TCP编程

    在这个"通过JNI实现C++与JAVA相互调用之TCP编程"的示例中,我们探讨的是如何使用JNI来实现TCP通信,其中C++作为底层通信引擎,而Java则负责上层应用逻辑。 首先,TCP(Transmission Control Protocol)是一种面向...

    android 简单的java c++ 相互调用源码

    在Android平台上,Java和C++代码的相互调用是一个常见的需求,这主要得益于JNI(Java Native Interface)技术。JNI使得Android应用能够利用C/C++的高效性能和丰富的库资源,同时保持Java的跨平台特性。本资料包...

    cocos2dx 3.3工程,C++通过JNI与Java相互调用

    总的来说,C++通过JNI与Java的相互调用在Cocos2dx 3.3中是一个关键的集成技术,它使得开发者能够充分利用C++的性能优势,同时又能利用Java的生态系统和Android SDK功能。这个过程需要对C++、Java和Android开发有深入...

    java与C++的相互调用

    Java和C++之间的相互调用是跨语言编程中常见的需求,特别是在开发高性能、低级操作或者利用现有C/C++库的场景下。JNI(Java Native Interface)是Java平台标准的一部分,它提供了一种机制,使得Java代码能够调用C/...

    java调用c++demo(避免不必要的通信调用)

    当我们需要利用Java的平台独立性和C++的高性能时,就需要找到一种方法让两者协同工作。本篇将深入探讨如何在Java中调用C++代码,以及如何避免不必要的通信开销,以提高整体程序的效率。 首先,Java调用C++最常用的...

    C++调用java代码的JNI实现

    在软件开发领域,经常会出现不同语言之间相互调用的需求。本文将深入探讨如何使用C++通过JNI(Java Native Interface)调用来实现对Java代码的调用,特别关注于用户身份验证与权限管理功能的实现。 #### JNI简介 ...

    Android中C/C++调用Java代码

    JNI提供了一种机制,允许Java代码和native代码之间相互调用。下面我们将详细介绍Android中C/C++调用Java代码的过程。 首先,我们需要了解JNI中的基本概念。JNI中有两个重要的概念:JNIEnv和jclass。JNIEnv是JNI环境...

    android studio项目java C/C++ 相互调用

    在Android开发中,有时我们需要利用C或C++的高性能特性,比如处理图形计算、音频处理等,这时就需要在Java和C/C++之间进行交叉调用。Android Studio支持这种跨语言调用,主要通过Android Native Development Kit ...

    coco2dx JNI示例,java c++相互调用

    在这个"Coco2dx JNI示例,java c++相互调用"的项目中,我们将深入探讨如何在Cocos2dx游戏引擎中使用JNI实现Java和C++之间的通信。 1. **JNI基础** JNI是Java平台提供的一个标准接口,它允许Java代码调用本地(非...

    JNI实现java cpp相互调用

    JNI实现java cpp相互调用,包括动态注册和静态注册两种方式,具体包含 静态方式实现: C/C++中访问Java方法 C/C++中访问Java父类的方法 C/C++中访问/修改Java变量 Java中访问C/C++方法 Java中访问/修改C/C++变量 ...

    visual studio 2019下C++通过JNI调用JAVA代码

    总的来说,通过JNI,C++和Java代码可以相互调用,提供了一种灵活的跨语言通信机制。在Visual Studio 2019中,你可以方便地利用这个特性来构建混合语言的应用,实现特定功能的优化或者充分利用已有的C++库。在实际...

    《C++ for Java Programmers》高清完整英文PDF版

    书中特别提到了如何使用Java原生接口(JNI),这是为了在Java和C++之间建立桥接,让两种语言可以相互操作。 知识点八:C++的细节。书中对于C++程序员在实际编程中可能会遇到的C语言风格的细节进行了深入的讨论。 ...

    java C#相互调用的全新方式

    本文将深入探讨“Java与C#相互调用的全新方式”,结合给定的标签“源码”和“工具”,我们将重点讨论如何通过中间件或接口实现这种交互,并提供一种可能的解决方案——AMFCall。 Java和C#的互操作性通常通过以下几...

Global site tag (gtag.js) - Google Analytics