1 宏 相关知识点
#ifndef CLIONCPPPROJECT_T2_H // 如果没有定义这个宏 解决循环拷贝的问题
#define CLIONCPPPROJECT_T2_H // 就定义这个宏
// 第一次能够进来
// 第二次 第n此进不来 直接 解决循环拷贝的问题了
// ---------------
#ifndef isRelease // 如果没有isRelease这个宏
#define isRelease 1 // 是否是正式环境下 【我就定义isRelease这个宏】
#if isRelease == true
#define RELEASE // 正式环境下 定义RELEASE宏
#elif isRelease == false
#define DEBUG // 测试环境下 定义DEBUG宏
#endif // 结束里面的if
#endif // 结束里面的if
#endif //CLIONCPPPROJECT_T2_H // 结束外面的if
#ifndef HONG// 如果没有定义这个宏
#define HONG// 我就定义宏
#ifdef HONG// 是否定义了这个宏
for (int i = 0; i < 6; ++i) {
cout << "HONG 1" << endl;
}
// 省略 500行 ...
#ifdef HONG// 是否定义了这个宏
for (int i = 0; i < 6; ++i) {
cout << "HONG 2" << endl;
}
// 省略 500行 ...
#undef HONG// 取消宏的定义,下面的代码,就没法用这个宏了,相当于:没有定义过HONG宏
#ifdef HONG
cout << "你定义了HONG宏" << endl;
#else
cout << "你没有定义了HONG宏" << endl;
#endif
#endif
#endif
#endif
//宏替换
#define VALUE_I 9527
int i = VALUE_I; // 预处理阶段 宏会直接完成文本替换工作,替换后的样子:int i = 9527;
#define ADD(n1, n2) n1 + n2
int r = ADD(1+1, 2+2);
r = 6 ;
#define CHE(n1, n2) n1 * n2
r = CHE(1+1, 2+2);
// 会被替换成
r = 1+1 * 2+2;
// 计算先乘除 ,后加减 最后结果 r = 5 ;
r = 5
c++ 日志打印
#include <android/log.h>
#define TAG "info"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
2 JNI 基本交互
public native String stringFromJNI();
extern "C" // 无论是C还是C++ 最终是调用到 C的JNINativeInterface,所以必须采用C的方式 extern "C"
JNIEXPORT // 标记该方法可以被外部调用(VS上不加入 运行会报错, AS上不加入运行没有问题)
jstring // Java <---> native 转换用的 方法返回
JNICALL // 代表是 JNI标记,可以少
// java + 包名 + 类名 + 方法名
Java_com_cn_mynativestudy_MainActivity_stringFromJNI
(
JNIEnv* env, // JNIEnv 对象 ,JNI的操作都需要 JNIEnv 的函数
jobject /* this */) { // MainActivity 的对象
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
public static native void changeAge();
extern "C"
JNIEXPORT void JNICALL
// 如果 java 中 是static 静态方法 ,JNI中 者传入该方法所对应类的class jclass MainActivity
Java_com_cn_mynativestudy_MainActivity_changeAge(
JNIEnv *env,
jclass clazz // MainActivity 的class
) {
jfieldID j_filed = env->GetStaticFieldID(clazz,"age","I");
env->SetStaticIntField(clazz,j_filed,22);
}
JNI 中的部分函数
extern "C"
JNIEXPORT void JNICALL
// 如果 java 中 是普通方法 ,JNI中 者传入该方法所对应类的对象 jobject MainActivity
Java_com_cn_mynativestudy_MainActivity_changeName(JNIEnv *env, jobject thiz) {
// 通过 jobject 对象 获取 class 对象
jclass j_cls = env->GetObjectClass(thiz);
// 通过 GetFieldID 函数 获取到 field 成员变量
// 第一个参数 ,jclass 通过转换得来 ,第二个参数 属性名 ,第三个参数 ,属性签名
jfieldID jfieldId = env->GetFieldID(j_cls,"name","Ljava/lang/String;");
// 获取成员变量的值 并强转成 jstring
jstring j_str = static_cast<jstring>(env->GetObjectField(thiz,jfieldId));
// jstring 转 char *
char * c_str = const_cast<char *>(env->GetStringUTFChars(j_str, NULL));
// 日志 打印
char * TAG = "info";
LOGD("native : %s\n", c_str);
LOGE("native : %s\n", c_str);
LOGI("native : %s\n", c_str);
//创建一个 新的 jstring
jstring newString = env->NewStringUTF("new String ");
// 成员变量赋值
env->SetObjectField(thiz,jfieldId,newString);
}
extern "C"
JNIEXPORT void JNICALL
// 如果 java 中 是static 静态方法 ,JNI中 者传入该方法所对应类的class jclass MainActivity
Java_com_cn_mynativestudy_MainActivity_changeAge(JNIEnv *env, jclass clazz) {
// 获取成员变量 GetStaticFieldID
jfieldID j_filed = env->GetStaticFieldID(clazz,"age","I");
// 赋值 SetStaticIntField
env->SetStaticIntField(clazz,j_filed,22);
}
c++ 中 调用 java中方法
public int add(int number1, int number2) {
return number1 + number2 + 8;
}
extern "C"
JNIEXPORT void JNICALL
Java_com_cn_mynativestudy_MainActivity_callAddMethod(JNIEnv *env, jobject thiz) {
// 获取类对象
jclass j_clz = env->GetObjectClass(thiz);
// 通过方法名 获取 methodid 对象
jmethodID j_med = env->GetMethodID(j_clz,"add","(II)I");
// 调用该方法
int num = env->CallIntMethod(thiz,j_med,5,5);
// num = 18 // 5+5+8 = 18 ;
}
Java的引用类型 --- Lxxx/xxx/xx/类名;
Java的String --- Ljava/lang/String;
Java的array int[] --- [I double[][][][] --- [[[D
int add(char c1, char c2) ---- (CC)I
void a() === ()V