上一篇研究到如何在c++层传值给lua。在本篇中,我们将以c++为中间层,从Java传一个string到lua层。
首先跑到proj.android那边新建一个java文件,这里创建了com.exkulo.test.JavaBridge,创建了一个类,带了一个static方法。
package com.exkulo.test;
import android.widget.Toast;
public class CppJavaBridge {
static String getStringFromJava() {
return "a string from Java";
}
}
然后跑到这个文件夹,跑一遍javac CppJavaBridge.java和javap -s CppJavaBridge得到签名。注意注意,这里的签名要看清楚最后有没有带分号!!
在上一篇的bridge文件夹中新建JavaBridge.h和JavaBridge.cpp。代码分别为:
#include "platform/CCPlatformConfig.h"
#if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include "platform/CCPlatformConfig.h"
#include "cocos2d.h"
#include "CCLuaEngine.h"
#include <string>
#include "platform/android/jni/JniHelper.h"
using namespace cocos2d;
class JavaBridge {
public:
std::string getStringFromJava();
static JavaBridge* getInstance();
};
#endif
#include "platform/CCPlatformConfig.h"
#if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include "JavaBridge.h"
JavaBridge *instance;
std::string JavaBridge::getStringFromJava(){
JniMethodInfo methodInfo;
JNIEnv* env = cocos2d::JniHelper::getEnv();
jclass sdkManager_cls = env->FindClass("com/exkulo/test/CppJavaBridge");
jmethodID init_mid = env->GetStaticMethodID(sdkManager_cls, "getStringFromJava", "()Ljava/lang/String;");
auto ret = (jstring)env->CallStaticObjectMethod(sdkManager_cls, init_mid);
const char* chars = env->GetStringUTFChars(ret, 0);
return chars;
}
JavaBridge* JavaBridge::getInstance() {
if (instance == NULL) {
instance = new JavaBridge();
}
return instance;
}
#endif
这里声明了一个JavaBridge类,注意这里要设计成单例模式(其实随你喜欢)。然后在cpp文件里实现方法。
回到上一篇的JavaLuaBridgeToolkit,更改代码变成以下形式:
#include "JavaLuaBridgeToolkit.h"
#if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include "JavaBridge.h"
#else
#endif
int sayHello(lua_State *L){
string msgFromLua = luaL_checkstring(L, 1);
CCLOG("Hello~ from c++, msg from lua: %s", msgFromLua.c_str());
lua_pushstring(L, "Hello World From C++");
return 1;
}
int getStringFromJava(lua_State *L) {
#if(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
auto javaBridgeInstance = JavaBridge::getInstance();
auto str = javaBridgeInstance->getStringFromJava();
lua_pushstring(L, str.c_str());
#else
lua_pushstring(L, "a win32 msg");
#endif
return 1;
}
static const struct luaL_Reg myLib[] =
{
{ "sayHello", sayHello },
{ "getStringFromJava", getStringFromJava },
{ NULL, NULL }
};
int register_javaLuaBridgeToolkit(lua_State* L) {
luaL_register(L, "JavaLuaBridge", myLib);
return 1;
}
这里多注册了一个方法,当在android下的时候返回JavaBridge返回的值,否则返回一个默认值。
最后,在上一篇说的android.mk里添加对JavaBridge.cpp的引用。
有可能遇到的问题:
JniHelper中引用jni.h失败。
解决方法:直接用一个判断平台的#if包起来即可。