jni的使用

我们今天讲的一共一个两部分,一部分是c++调java,另一部分是java调c++

首先说下,jni只有在安卓平台下才会用到,所以在包含头文件时要加个条件编译

#if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include "platform/android/jni/JniHelper.h"
#endif

接着通过一小段代码来说明一下这个类的用法。

#if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
//    typedef struct JniMethodInfo_
//    {
//        JNIEnv *    env;
//        jclass      classID;
//        jmethodID   methodID;
//    } JniMethodInfo;
    JniMethodInfo info;
    //getStaticMethodInfo判断java定义的静态函数是否存在,返回bool
    bool ret = JniHelper::getStaticMethodInfo(info,"org/cocos2dx/cpp/TestJni","func1","(Ljava/lang/String;)V");
    if(ret)
    {
        log("call void func1() succeed");
        //传入类ID和方法ID,小心方法名写错,第一个字母是大写
        jstring jstr =info.env->NewStringUTF("1");
        info.env->CallStaticVoidMethod(info.classID,info.methodID,jstr);
    }
#endif

JniMethodInfo是一个结构体,关于它,大家自己看源码,我尽量说重点。说下JniHelper::getStaticMethodInfo的参数,第一个填自己info结构体变量,通过该方法会为info的classID,methodID赋值,第二个参数为org/cocos2dx/cpp下的TestJni这个类,第三个参数为这个类的静态方法方法名,第四个参数为该方法的参数与返回类型,它把调用函数的参数写到前面的括号中,返回值跟在括号的后边,和我们平时书写函数的时候正好相反了。
这里有一点要强调下,func方法的参数为一个String类型的字符串,那当我们给这个方法传个参数时要怎么写呢?我们必须通过info.env->NewStringUTF(“1”);获得到新的字符串,然后将这个参数传给java。要不然会使程序崩掉。至于为什么,我就不知道了。

介绍完c++部分,接下来说下对应参数的类型,分别有方法参数类型与方法返回值类型。附上两张对应的图。

方法参数类型:这里写图片描述

方法返回值类型:这里写图片描述

好了,c++部分的代码就写的差不多了,接下来写java的代码。java要写的代码非常简单。

package org.cocos2dx.cpp;
import android.util.Log;
public class TestJni
{
    public static void func1()
    {
        Log.e("xiaota","java:func1,called succeed!");
    }
}

我们在org.cocos2dx.cpp路径下创建一个TestJni类,类中有一个名为func1,参数为空,返回值为void的静态方法。注意这个方法一定要是静态的,然后参数与返回类型一定要与c++代码部分一致,否则就调不到了。

好了,这样子我们c++调用java的代码就写完了。

————————————————————————————————————

接下来,我们讲下用java代码调用c++代码
首先先讲java部分。java部分非常简单。

package org.cocos2dx.cpp;
import android.util.Log;
public class TestJni
{
    public native static void alipayPayOk(String itemId);
    public void test(){
        this.alipayPayOk("1");
    }
}

上面就是所有的java代码,很简单吧,和普通方法没有什么不同,只是在方法前加了一个native关键字,然后在要调用的地方直接像调普通方法一样调就行了。

接下来到c++部分,c++部分会比较麻烦一点,当也挺简单的,照着写就行了。先上代码!

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
extern "C"
{
    JNIEXPORT  void Java_org_cocos2dx_cpp_AppActivity_alipayPayOk(JNIEnv*  env, jobject thiz, jstring productID)
    {
        BuyDiamondLayer::m_layer->buyGold(Value(productID).asInt());
    }
}
#endif

还是一样的,我们在包含头文件时要加个条件编译,因为jni只用在安卓平台下才有用到。

复杂的东西我们不用管(其实我也不大懂~),我只说下你们要改哪里就好了。首先 JNIEXPORT 这个是jni的关键字,表示此函数是要被jni调用的。接着,void的表示该方法的返回值为空,再接着Java_org_cocos2dx_cpp_AppActivity_alipayPayOk中,Java我们不用改,我们要改的是org_cocos2dx_cpp_AppActivity。其中org_cocos2dx_cpp为路径,AppActivity为路径下的文件名。
接着我们说下参数,前面两个JNIEnv* env, jobject thiz,这两个我们不用管。后面一个jstring productID,这个就是我们java传过来的参数。

好了,这样子c++部分的代码也就完成了。我们c++调java,java调c++就大功告成了!赶紧写代码实现去吧~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值