JNI学习笔记

1.xxx.java生成 xxx.class文件 和专属的.h文件命令

javac - h . xxx.java

2.查看当前xxx.java文件所有签名信息

//首先得到xxx.class文件
执行->javap -s -p xxx.class
//得到结果如下,descriptor后的就是签名信息()内的是参数;V是返回值
public class com.example.cb.test.native1.FieldTest {
  public int a;
    descriptor: I
  public static int b;
    descriptor: I
  public com.example.cb.test.native1.FieldTest();
    descriptor: ()V

  public native void testField();
    descriptor: ()V

  public native void testStaticField();
    descriptor: ()V

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V

  static {};
    descriptor: ()V
}

3.Java调C 传入String,拼接String返回

//************************************java代码************************************
package com.example.cb.test.native1;

public class StringTest {

    static {
    //这里是全路径
        System.load("E:\\CPlae\\NativeTest\\cmake-build-debug\\libstringLib.dll");
    }

    public native static String sayHello(String txt);

    public static void main(String[] args) {
        String txt = sayHello("张三");
        System.err.println(txt);
    }
}

//************************************C代码************************************
#include "jni.h"
#include 
#include 


JNIEXPORT jstring JNICALL Java_com_example_cb_test_native1_StringTest_sayHello
        (JNIEnv *env, jobject jobject, jstring jstr) {
    const char *c_str = NULL;
    jboolean isCopy;
    c_str = (*env)->GetStringUTFChars(env, jstr, &isCopy);
    if (c_str == NULL)return NULL;

//    //第一种方式 char *拼接
//    //1.malloc 分配空间
//    //2.初始化
//    //3.拼接
//    char buff[128] = {0};
//    sprintf(buff, "Hello 你好%s", c_str);

    //另一种 直接用库string.h 库中的API
    char hello[] = "Hello  你的名字是";
    char *p_str = strcat(hello, c_str);

    //用完释放
    (*env)->ReleaseStringUTFChars(env, jstr, c_str);
    return (*env)->NewStringUTF(env, p_str);
}

//************************************运行结果************************************
Hello  你的名字是张三

Process finished with exit code 0

4.C调用java的变量

//************************************java代码************************************
package com.example.cb.test.native1;

public class FieldTest {


    public int a = 1;

    public static int b = 2;

    public native void testField();

    public native void testStaticField();

    static {
        System.load("E:\\CPlae\\NativeTest\\cmake-build-debug\\libfield.dll");
    }

    public static void main(String[] args) {
        FieldTest fieldTest = new FieldTest();
        fieldTest.testField();
        fieldTest.testStaticField();

        System.err.println("1->" + fieldTest.a);
        System.err.println("2->" + fieldTest.b);
    }
}

//************************************C代码************************************
//C里面不像java区分private和public
//只区分 static和非static

/*
 * 获取JAVA中变量,并改变值
 * Class:     com_example_cb_test_native1_FieldTest
 * Method:    testField
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_example_cb_test_native1_FieldTest_testField
        (JNIEnv *env, jobject jobject) {
    //第一步,得到这个类
    jclass clz = (*env)->GetObjectClass(env, jobject);
    //第二步,得到fieldID
    jfieldID jfid = (*env)->GetFieldID(env, clz, "a", "I");
    //第三步,得到a变量
    jint a = (*env)->GetIntField(env, jobject, jfid);
    printf("C中得到JAVA中的变量a=%d\n", a);
    (*env)->SetIntField(env, jobject, jfid, a + 100);
}

/*
 * 获取JAVA中静态变量,并改变值
 * Class:     com_example_cb_test_native1_FieldTest
 * Method:    testStaticField
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_example_cb_test_native1_FieldTest_testStaticField
        (JNIEnv *env, jobject jobject) {
    jclass clz = (*env)->GetObjectClass(env, jobject);
    jfieldID fid = (*env)->GetStaticFieldID(env, clz, "b", "I");
    jint b = (*env)->GetStaticIntField(env, clz, fid);
    printf("C中获取静态的b=%d\n", b);
    (*env)->SetStaticIntField(env, clz, fid, b + 66);
}

//************************************运行结果************************************
1->101
2->101
C中得到JAVA中的变量a=1
C中获取静态的b=2

Process finished with exit code 0

你可能感兴趣的:(JNI)