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

  1. Java端要做的事:把要被调用的函数定义好。

    // 定义在org/cocos2dx/cpp/AppActivity.java文件里的函数
    public static void java_func_1(int i, String s) {}
  2. C++端要做的事:

    // 包含头文件
    #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
        #include "platform/android/jni/JniHelper.h"
    #endif
    
    // 常见一点的写法
    void YourClass::YourFunc(int IntPara, const std::string& StrPara)
    {
    #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
    
        // 声明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);
        }
    #endif
    }
    
    // 更简单一点的写法
    void YourClass::YourFunc(int IntPara, const std::string& StrPara)
    {
    #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
        // 这么写不用去判断方法是否存在,也不需要去把C++的数据类型转成Java的数据类型。(PS:如果方法不存在,也不会出错)
        cocos2d::JniHelper::callStaticVoidMethod("org/cocos2dx/cpp/AppActivity", "java_func_1", i, str);
    #endif
    }

Java调C++

  1. Java端要做的事:把要被调用的函数声明好。

    public static native void funcName2(int i, String s);

    在java代码里合适的地方调用这个函数。另外我发现声明不需要写在调用处之前。为啥我也不知道。

  2. C++端要做的事:随便找个cpp文件,写上这个函数的实现部分。

    #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
    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());
        }
    }
    #endif

    另外,我发现一个问题,这个函数似乎不能带下划线,比方说我写成func_Name2,并且我在声明处、调用处、定义处都做了相应的修改,还是不行,而且会引起崩溃。