cocos2d-x中的Jni使用(C++与Andriod方法互调)


15235313_z0yP.jpg

前提条件:

1.操作的游戏工程和cocos2d_x游戏引擎是一个目录的

2.跟jni相关的C++代码文件放在proj.android\jni\hellocpp目录下,每加一个cpp文件,都需在proj.android\jni的Andriod.mk文件中添加:

屏幕快照 2015-07-06 23.10.17.png

这个在 c++调用 java 的时候是为了容易找到,所以在 hellocpp 目录下,当然可以放到其他目录

3.跟jni相关的java代码文件放在proj.android\src目录下,可以另外建立一个文件夹,比如 ioss

【一】C++调用Andriod接口

1、定义一个.h文件“test.h”,内容:

#ifndef __jnihe__test__
#define __jnihe__test__
#include <stdio.h>
extern "C"
{
    void showExitPt(const char *title,const char *msg);
}
#endif /* defined(__jnihe__test__) */

2.定义一个.cpp文件“test.cpp”,内容:

//
//  test.cpp
//  jnihe
//
//  Created by admin on 15/7/6.
//
//

#include "test.h"
#include "cocos2d.h"

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

//表示proj.android/src/ios/JniTestHelper.java的,在该文件里有showTipDialog的实现
#define CLASS_NAME "ioss/jnitesthelper"
//事实上,showExitPt一般都是跟showTipDialog同名的,这里为了区分,写成不一样
void showExitPt(const char *title,const char *msg)
{
    JniMethodInfo t;
    if(JniHelper::getStaticMethodInfo(t, CLASS_NAME, "showTipDialog", "(Ljava/lang/String;Ljava/lang/String;)V"))
    {
        
        jstring jTitle = t.env->NewStringUTF(title);
        jstring jMsg = t.env->NewStringUTF(msg);
        //根据该方法的返回值调用对应的CallStaticxxxMethod方法,如CallStaticIntMethod
        t.env->CallStaticVoidMethod(t.classID, t.methodID, jTitle, jMsg);
        t.env->DeleteLocalRef(jTitle);
        t.env->DeleteLocalRef(jMsg);
    }
}
#endif

3.java实现,这里就是c++调用安卓工程里面的showTipDialog这个功能。

定义一个JniTestHelper.java文件,就是在刚才的proj.android\src目录下的自己建的那个文件夹里面建立一个JniTestHelper.java文件。

屏幕快照 2015-07-06 23.19.21.png

也可以使用 eclipse新建一个类

屏幕快照 2015-07-06 23.17.41.png

内容:

package ioss;

import android.os.Message;

public class jnitesthelper {

	public static void showTipDialog(final String title, final String text)
    {
        System.out.println("sssssssssssssssss");
    }
}

4.程序使用

这时候调用showExitPt,就会自动调用安卓的 showTipDialog 这个方法了,就会输出 ssssss

#include "HelloWorldScene.h"
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include "../proj.android/jni/hellocpp/test.h"
#endif
USING_NS_CC;
CCScene* HelloWorld::scene()
{
    CCScene *scene = CCScene::create();
    HelloWorld *layer = HelloWorld::create();
    scene->addChild(layer);
    return scene;
}
bool HelloWorld::init()
{
    // 1. super init first
    if ( !CCLayer::init() )
    {
        return false;
    }
    CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
    CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
    CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
                                        "CloseNormal.png",
                                        "CloseSelected.png",
                                        this,
                                        menu_selector(HelloWorld::menuCloseCallback));
    
	pCloseItem->setPosition(ccp(origin.x + visibleSize.width - pCloseItem->getContentSize().width/2 ,
                                origin.y + pCloseItem->getContentSize().height/2));
    CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
    pMenu->setPosition(CCPointZero);
    this->addChild(pMenu, 1);
    CCLabelTTF* pLabel = CCLabelTTF::create("Hello World", "Arial", 24);
    pLabel->setPosition(ccp(origin.x + visibleSize.width/2,
                            origin.y + visibleSize.height - pLabel->getContentSize().height));
    this->addChild(pLabel, 1);
    CCSprite* pSprite = CCSprite::create("HelloWorld.png");
    pSprite->setPosition(ccp(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));
    this->addChild(pSprite, 0);
    return true;
}
void HelloWorld::menuCloseCallback(CCObject* pSender)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
    {
        
    }
#elif  (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
    {
        showExitPt("ss","ssss");
    }
#endif
}

【二】Andriod调用C++接口

1.在test2.h中加入实现内容:

#ifndef __jnihe__test2__
#define __jnihe__test2__
#include <stdio.h>
#ifdef __cplusplus
extern "C"   //这个很重要
{
#endif
void setout(const char*);
#ifdef __cplusplus
}
#endif
#endif /* defined(__jnihe__test2__) */

2.在test2.cpp中加入实现内容:将C++实现与Andriod工程中的声明关联

#include "cocos2d.h"
USING_NS_CC;
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include <jni.h>
#include "platform/android/jni/JniHelper.h"
#ifdef __cplusplus
extern "C"
{
#endif
void setout(const char*s)
{
    CCLOG("mmmmmmmmmmmmmmmmmmmmm");
}
//1.Java_:是格式,必须加的
//2.ioss_jnitesthelper:是路径proj.android\src\ios\jnitesthelper.java去掉proj.andriod\src的部分
//3.setoutsm:是Andriod工程中声明的名字
//4.中间需要_分开
void Java_ioss_jnitesthelper_setoutsm(JNIEnv *env,jobject thiz)
{
    setout("s");
}
#ifdef __cplusplus
}
#endif
#endif

3.Andriod工程中的声明(JniTestHelper.java):

package ioss;

import android.os.Message;

public class jnitesthelper {

//这个调用功能就是接着上面的那个例子,点击按钮,输出 ssss,并且调用外面的setoutsm函数,输出其他东西,从而证明调用了
	public static void showTipDialog(final String title, final String text)
    {
        System.out.println("sssssssssssssssss");
        jnitesthelper.setoutsm();
    }
	public static native void setoutsm();//这句就是声明的函数,native 关键字的作用就是声明这个 setoutsm 函数是在 java 外实现的
}

4.程序调用:

程序调用这里就是上面的那句jnitesthelper.setoutsm();就是点击按钮开始调用,会输出 c++的 mmmm

【三】demo 下载

Github下载地址:https://github.com/DamonHu/jniDemo

GitOsc下载地址:http://git.oschina.net/DamonHoo/jniDemo

参考链接

原文作者:何卫

转载请注明,原文链接:http://www.cnblogs.com/hewei2012/p/3376616.html

本文在原文的基础上运行后修改,感谢原文作者的说明

Last modification:January 1st, 1970 at 08:00 am
如果看了这个文章可以让你少加会班,可以请我喝杯可乐
已打赏名单
微信公众号

Leave a Comment