1、JNI基础知识
(1)部分代码
# include <inttypes.h> /* C99 */
typedef uint8_t jboolean;
/* unsigned 8 bits */
typedef int8_t jbyte;
/* signed 8 bits */
typedef uint16_t jchar;
/* unsigned 16 bits */
typedef int16_t jshort;
/* signed 16 bits */
typedef int32_t jint;
/* signed 32 bits */
typedef int64_t jlong;
/* signed 64 bits */
typedef float jfloat;
/* 32-bit IEEE 754 */
typedef double jdouble;
/* 64-bit IEEE 754 */
#else
typedef unsigned char jboolean;
/* unsigned 8 bits */
typedef signed char jbyte;
/* signed 8 bits */
typedef unsigned short jchar;
/* unsigned 16 bits */
typedef short jshort;
/* signed 16 bits */
typedef int jint;
/* signed 32 bits */
typedef long long jlong;
/* signed 64 bits */
typedef float jfloat;
/* 32-bit IEEE 754 */
typedef double jdouble;
/* 64-bit IEEE 754 */
#endif
/* "cardinal indices and sizes" */
typedef jint jsize;
#ifdef __cplusplus
/*
* Reference types, in C++
*/
class _jobject {};
class _jclass : public _jobject {};
class _jstring : public _jobject {};
class _jarray : public _jobject {};
class _jobjectArray : public _jarray {};
class _jbooleanArray : public _jarray {};
class _jbyteArray : public _jarray {};
class _jcharArray : public _jarray {};
class _jshortArray : public _jarray {};
class _jintArray : public _jarray {};
class _jlongArray : public _jarray {};
class _jfloatArray : public _jarray {};
class _jdoubleArray : public _jarray {};
class _jthrowable : public _jobject {};
typedef _jobject* jobject;
typedef _jclass* jclass;
typedef _jstring* jstring;
typedef _jarray* jarray;
typedef _jobjectArray* jobjectArray;
typedef _jbooleanArray* jbooleanArray;
typedef _jbyteArray* jbyteArray;
typedef _jcharArray* jcharArray;
typedef _jshortArray* jshortArray;
typedef _jintArray* jintArray;
typedef _jlongArray* jlongArray;
typedef _jfloatArray* jfloatArray;
typedef _jdoubleArray* jdoubleArray;
typedef _jthrowable* jthrowable;
typedef _jobject* jweak;
#else /* not __cplusplus */
/*
* Reference types, in C.
*/
typedef void* jobject;
typedef jobject jclass;
typedef jobject jstring;
typedef jobject jarray;
typedef jarray jobjectArray;
typedef jarray jbooleanArray;
typedef jarray jbyteArray;
typedef jarray jcharArray;
typedef jarray jshortArray;
typedef jarray jintArray;
typedef jarray jlongArray;
typedef jarray jfloatArray;
typedef jarray jdoubleArray;
typedef jobject jthrowable;
typedef jobject jweak;
#endif /* not __cplusplus */
(2)Cocos2d-x封装JniHelper代码
typedef struct JniMethodInfo_
{
JNIEnv * env;
jclass classID;
jmethodID methodID;
} JniMethodInfo;
class CC_DLL JniHelper
{
public:
static JavaVM* getJavaVM();
static void setJavaVM(JavaVM *javaVM);
static const char* getExternalAssetPath();
static void setExternalAssetPath(const char* externalAssetPath);
static jclass getClassID(const char *className, JNIEnv *env=0);
static bool getStaticMethodInfo(JniMethodInfo &methodinfo, const char *className, const char *methodName, const char *paramCode);
static bool getMethodInfo(JniMethodInfo &methodinfo, const char *className, const char *methodName, const char *paramCode);
static std::string jstring2string(jstring str);
private:
static JavaVM *m_psJavaVM;
static std::string m_externalAssetPath;
};
(3)JniHelper常用函数
a:getStaticMethodInfo:用来判断java类中静态函数是否存在,初始化结构体JniMethodInfo。该结构体封装了JNIEnv*和java.lang.Class、函数ID。这样可以使用JNIEnv*调用CallStaticXXXMethod(jclass clazz,jmethodID methodID,...)和CallXXXMethod(jobject obj,jmethodID methodID,...)等常用函数,其中XXX代表函数返回值类型,如void、int等。如下代码:
JniMethodInfo info;
bool ret = JniHelper::getStaticMethodInfo(info,"org/cocos2dx/cpp/AppActivity","getObj","()Ljava/lang/Object;");
jobject jobj;
if(ret)
{
log("call void getObj() succeed");
jobj = info.env->CallStaticObjectMethod(info.classID,info.methodID);
}
bool re = JniHelper::getMethodInfo(info,"org/cocos2dx/cpp/AppActivity","func1","()V");
if(re)
{
log("call func1 succeed");
info.env->CallVoidMethod(jobj,info.methodID);
}
注意:使用该代码需要加一下头文件,判断平台
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
#include <jni.h>
#include "../../cocos2d/cocos/platform/android/jni/JniHelper.h"
#include <android/log.h>
#if 1
#define LOG_TAG "JniHelper"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
#else
#define LOGD(...)
#endif
#endif
b:getMethodInfo:用于Java类的非静态函数
类型签名 | Java类型 |
Z | boolean |
B | byte |
C | char |
S | short |
I | int |
J | long |
F | float |
D | double |
L full-qualified-class; | 完全限定的类 |
[ type | type[ ] |
(arg-types) ret-type | 方法类型 |
如java方法:long f(int n,String s,int[] arr); 类型签名为:(ILjava/lang/String;[I)J。注意L后的分号,[是半开的,要与类型签名完全一致。
下一篇博客将写一个例子,来体会C++调Java的使用