cocos2dx java调用c++

在做支付接入时,大都采用cocos2d-x 的jnihelper调用java实现接入,但光c++调java是不够的, 如第三方写的支付接口 支付成功了他们有一个onSuccess事件,可是这个方法是写在java端的AppActivity.java里的,但实际给用户加钱是写在cocos2d-x c++工程里的,java怎么通知c++工程支付成功了?发消息显然不可能,sdk没提供这个接口,只好在java端的onSuccess方法调用c++类函数了,可是网上大都是利用jnihelper调用java教程,很少有java调c++的,只好自己苦苦搜寻答案了

c++工程端,因为我们对c++比较熟悉,就从它开始吧!

1. 定义供java调用的native接口

//这个方法专门给java调用

extern "C"  //org.cocos2dx.cpp
{
	JNIEXPORT void JNICALL Java_org_cocos2dx_cpp_MyHelper_setMoney(jnienv *env,jobject thiz,jint money)
	{
		int m = (int)money;
		User::shared()->setMoney(money);
	}
};
必须定义extern “C”,那长长的函数名也好理解,Java是固定开头, org_cocos2dx_cpp就是你的包名"org.cocos2dx.cpp"中间以"_"隔开,MyHelper是java文件里哪一个类会调用这个函数,setMonet是供java类调用函数名 ,后面参数 jnienv* env,jobject thiz这两个固定,后面jint money是函数里用到的参数,可以自己加,注意转成jni中java能识别的类型,如int改成jint
函数体里我们调用了类里的setMoney方法,这就解决了怎么调一个类里的方法的难题.
给出提供这个java接口的全代码
user.h
#ifndef _User_
#define _User_

#include "cocos2d.h"
class HelloWorld;

class User
{
public:
	User();
	~User();

	HelloWorld* _scene;
	static User *shared();  //定义单例方法
	static User* s_UserShared;

	void setMoney(int money); //设置钱数
protected:
	int _money;
private:
};
#endif // !_User_
user.cpp
#include "User.h"
#include "HelloWorldScene.h"
USING_NS_CC;
using namespace std;

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include <jni.h>
#include "platform/android/jni/JniHelper.h"
#include  <android/log.h>
//这个方法专门给java调用

extern "C"  //org.cocos2dx.cpp
{
	JNIEXPORT void JNICALL Java_org_cocos2dx_cpp_MyHelper_setMoney(jnienv *env,jobject thiz)
	{
		//int m = (int)money;
		User::shared()->setMoney(100);
	}
};

#endif



User* User::s_UserShared = nullptr;
User::User()
{
	_money = 0;
	_scene = nullptr;
}

User::~User()
{

}

User* User::shared()
{
	if (s_UserShared == nullptr)
	{
		s_UserShared = new User();
		return s_UserShared;
	}
	return s_UserShared;
}

void User::setMoney(int money)
{
	_money = money;
	log("OK! _money = %d",_money);
	if (_scene!=nullptr)
	{
		String* str = String::createWithFormat("Coins: %d",_money);
		_scene->_pLabal->setString(str->getCString());
	}
}
那个helloworldscene变量大家请无视,我只是为了想看效果用的,结果失败了,最后打出Log了事,不要误导大家

java端:

声明java调用c++的接口,我定义一个辅助工具类Helper里调用这个接口,建议你也采用这样的写法,显得整洁

/**
* 这里是java调用cocos2d-x的地方
* @param money 钱
*/
public static native void setMoney();

接口其实就是加个native关键字,下面给出完整的MyHelper.java源码:

package org.cocos2dx.cpp;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.widget.Toast;

public class MyHelper {

	private static Context s_context;
	 
	 /**
	 * 初始化内容信息
	 * @param context
	 */
	 public static void initContext(Context context){
	  s_context = context;
	 }
	 
	 /**
	  * 这里是java调用cocos2d-x的地方
	  * @param money 钱
	  */
	 public static native void setMoney();
}
那什么initContext无关紧要,记住这个类在org.cocos2d.cpp包里,

现在是调用部分:

这里是最关键的一步,早先老是失败是因为java端没有打包c++的编译.so。在android.mk里把定义那个接口的User类加进来,使之能打包到工程一起

LOCAL_SRC_FILES := hellocpp/main.cpp \
../../Classes/AppDelegate.cpp \
../../Classes/HelloWorldScene.cpp \
../../Classes/User.cpp
java主启动文件appActitvy.java里,在要调用这个接口方法之前要包含c++包库,一定要记住!

static { System.loadLibrary("cocos2dcpp"); }

然后就可以调用了:MyHelper.setMoney(); 这样就不会报找不到此函数错误

完整AppActivity.java类源码:

package org.cocos2dx.cpp;

import org.cocos2dx.lib.Cocos2dxActivity;

import android.R.integer;
import android.os.Bundle;

public class AppActivity extends Cocos2dxActivity {

//public static native void setMoney(int money);

static { System.loadLibrary("cocos2dcpp"); }
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

System.out.println("log");
MyHelper.setMoney();

}
}

为了大家便于学习,给出完整源码,对比整理下即可用在自己的工程里:

源码下载

相关文章

    本文实践自 RayWenderlich、Ali Hafizji 的文章《...
Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@1...
第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从C...
    Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发...
1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《...
   Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试...