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 <stdio.h>
#include <string.h>
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