1,基本数据类型转换表:
Java | Native类型 | 符号属性 | 字长 |
boolean | jboolean | 无符号 | 8位 |
byte | jbyte | 无符号 | 8位 |
char | jchar | 无符号 | 16位 |
short | jshort | 有符号 | 16位 |
int | jint | 有符号 | 32位 |
long | jlong | 有符号 | 64位 |
float | jfloat | 有符号 | 32位 |
double | jdouble | 有符号 | 64位 |
引用数据类型的转换:
Java引用类型 | Native类型 | Java引用类型 | Native类型 |
All object | jobject | char[] | jcharArray |
java.lang.class实例 | jclass | short[] | jshortArray |
java.lang.String实例 | jstring | int[] | jintArray |
object[] | jobjectArray | short[] | jshortArray |
boolean[] | jbooleanArray | long[] | jlongArray |
byte[] | jbyteArray | double[] | jdoubleArray |
java.lang.Throwable实例 | jthrowable | float[] | jfloatArray |
2,再就是signature,也就是签名了。signature的书写规则如下:
()中的字符表示参数,后面的则代表返回值,如“()V”就表示void Func(), “(II)V”表示void Func(int, int)等。具体的每个字符对应关系如下:
字符 java类型 C类型
V void void
Z jboolean boolean
I jint int
J jlong long
D jdouble double
F jfloat float
B jbyte byte
C jchar char
S jshort short
数组则以“[”开始,用两个字符表示
[I jintArray int[]
[F jfloatArray float[]
[D jdoubleArray double[]
[Z jbooleanArray boolean[]
[B jbyteArray byte[]
[C jcharArray char[]
[S jshortArray short[]
[J jlongArray long[]
如果java函数的参数是class,则以“L”开头,以“;”结尾,中间是用“/”隔开的包及类名,对应的C函数名的参数则为jobject,一个例外是String类,其对应类为jstring。
L java/lang/String; String jstring
Ljava/net/Socket;Socket jobject
例如:
JNI:
JNIEXPORT jboolean JNICALL Java_com_baidu_input_PlumCore_PlInit
(JNIEnv * env, jobject obj, jobjectArray names, jobject packageInfo)
签名内容:
{"PlInit","([Ljava/lang/String;Landroid/content/pm/PackageInfo;)Z", (void*)Java_com_baidu_input_PlumCore_PlInit },
Java:
protected native boolean PlInit(String[] fileNames, PackageInfo pi);
3,给个例子吧:
- #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
- //
- // #1 : 静态,无参数,无返回值
- // #2 : 静态,有参数,无返回值
- // #3 : 静态,有参数,有返回值
- // #4 : 非静态,无参数,无返回值
- // #5 : 非静态,有参数,无返回值
- // #6 : 非静态,有参数,有返回值
- //
- JniMethodInfo minfo;
- // #1
- if (JniHelper::getStaticMethodInfo(minfo,"com/chen/FunctionTester", "TF_S_NP_NR", "()V"))
- {
- minfo.env->CallStaticVoidMethod(minfo.classID, minfo.methodID);
- }
- // #2
- if(JniHelper::getStaticMethodInfo(minfo, "com/chen/FunctionTester", "TF_S_HP_NR","(I)V"))
- {
- minfo.env->CallStaticVoidMethod(minfo.classID, minfo.methodID,5);
- }
- // #3
- if (JniHelper::getStaticMethodInfo(minfo, "com/chen/FunctionTester", "TF_S_HP_HR","(I)I"))
- {
- jint __result;
- __result = minfo.env->CallStaticIntMethod(minfo.classID, minfo.methodID, 5);
- }
- // 非静态方法的调用需要从一个静态方法中获得非静态方法所属的对象。也就是说,调用了一
- // 个返回值类型为java.lang.Object的静态方法
- jobject jobj;
- // #4
- if (JniHelper::getStaticMethodInfo(minfo, "com/chen/FunctionTester",
- "getInstance", "()Ljava/lang/Object;"))
- {
- jobj = minfo.env->CallStaticObjectMethod(minfo.classID, minfo.methodID);
- if (JniHelper::getMethodInfo(minfo, "com/chen/FunctionTester","TF_US_NP_NR", "()V"))
- {
- minfo.env->CallVoidMethod(jobj, minfo.methodID);
- }
- }
- #endif
- package com.chen;
- public class FunctionTester {
- // 在调用非静态方法的时候,需要获得方法属于哪一个对象,所以必须有一个静态的实例。
- // 而且,这个实例没有办法直接访问,所以必须定义一个静态方法来获得这个实例
- // 这个实例必须以Object类型进行输出
- public static FunctionTester tester = null;
- public static Object getInstance(){
- if (tester == null){
- tester = new FunctionTester();
- }
- return tester;
- }
- /
- // #1 : 静态,无参数,无返回值
- // #2 : 静态,有参数,无返回值
- // #3 : 静态,有参数,有返回值
- // #4 : 非静态,无参数,无返回值
- // #5 : 非静态,有参数,无返回值
- // #6 : 非静态,有参数,有返回值
- /
- // #1
- public static void TF_S_NP_NR(){
- System.out.println("CALLED: TF_S_NP_NR");
- }
- // #2
- public static void TF_S_HP_NR(int _para){
- System.out.println("CALLED: TF_S_HP_NR, PARA: " + _para);
- }
- // #3
- public static int TF_S_HP_HR(int _para){
- System.out.println("CALLED: TF_S_HP_HR, PARA: " + _para);
- return 0;
- }
- // #4
- public void TF_US_NP_NR(){
- System.out.println("CALLED: TF_US_NP_NR");
- }
- // #5
- public void TF_US_HP_NR(int _para){
- System.out.println("CALLED: TF_US_HP_NR, PARA: " + _para);
- }
- // #6
- public int TF_US_HP_HR(int _para){
- System.out.println("CALLED: TF_US_HP_HR, PARA: " + _para);
- return 0;
- }
- }