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();

}
}

爲了大家便於學習,給出完整源碼,對比整理下即可用在自己的工程裏:

源碼下載



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章