cocos2dx jni
JNI
Java Native Interface。jni.h封装了Java代码和原生代码的交互功能,Cocos2dx再次封装成了JniHelper类。
C++数据类型转换成Java数据类型
C++ | java |
---|---|
void | V |
bool | Z |
char | C |
int | I |
short | S |
long | J |
float | F |
double | D |
std::string | Ljava/lang/Object; |
C++调Java
Java端要做的事:把要被调用的函数定义好。
// 定义在org/cocos2dx/cpp/AppActivity.java文件里的函数 public static void java_func_1(int i, String s) {}
C++端要做的事:
// 包含头文件 // 常见一点的写法 void YourClass::YourFunc(int IntPara, const std::string& StrPara) { // 声明jni方法结构体 cocos2d::JniMethodInfo jm; // 查找方法是否存在,分为静态方法和实例方法。这里的例子是静态方法。 bool bHave = cocos2d::JniHelper::getStaticMethodInfo(jm, "org/cocos2dx/cpp/AppActivity", "java_func_1", "(ILjava/lang/String;)V"); // 如果方法存在就能调用CallStaticMethod或者CallObjectMethod。 if (bHave) { // C++的字符串要转换成Java的字符串 jstring k1 = jm.env->NewStringUTF(str.c_str()); jm.env->CallStaticVoidMethod(jm.classID, jm.methodID, i, k1); jm.env->DeleteLocalRef(jm.classID); } } // 更简单一点的写法 void YourClass::YourFunc(int IntPara, const std::string& StrPara) { // 这么写不用去判断方法是否存在,也不需要去把C++的数据类型转成Java的数据类型。(PS:如果方法不存在,也不会出错) cocos2d::JniHelper::callStaticVoidMethod("org/cocos2dx/cpp/AppActivity", "java_func_1", i, str); }
Java调C++
Java端要做的事:把要被调用的函数声明好。
public static native void funcName2(int i, String s);
在java代码里合适的地方调用这个函数。另外我发现声明不需要写在调用处之前。为啥我也不知道。
C++端要做的事:随便找个cpp文件,写上这个函数的实现部分。
extern "C" { JNIEXPORT void Java_org_cocos2dx_cpp_AppActivity_funcName2(JNIEnv* env, jobject thiz, int i, jstring str1) { std::string str2 = cocos2d::JniHelper::jstring2string(str1); cocos2d::log("i=%d s=%s", i, str2.c_str()); } }
另外,我发现一个问题,这个函数似乎不能带下划线,比方说我写成
func_Name2
,并且我在声明处、调用处、定义处都做了相应的修改,还是不行,而且会引起崩溃。