预编译
预编译又叫预处理,宏定义,宏替换,关键字是#define
,其本质是替换文本。
C语言执行的过程
- 编译–>> 生成目标代码
- 合并–>> 将目标代码和C函数库合并,生成最终可执行文件
- 执行
预编译主要是在编译时期完成文本替换工作,常用的预编译指令有
#include
,ifndef
,#endif
,define
,
pragma once
在jni.h文件中,我们会有这样的代码,就是使用到了预编译
#if defined(__cplusplus)
typedef _JNIEnv JNIEnv;
typedef _JavaVM JavaVM;
#else
typedef const struct JNINativeInterface* JNIEnv;
typedef const struct JNIInvokeInterface* JavaVM;
#endif
这句话的意思是如果是C++,那么定义
_JNIEnv
和_JavaVM
分别定义成JNIenv
和JavaVm
,而如果是C语言,则将JNINativeInterface*
和JNIInvokeInterface*
分别定义成JNIEnv
和JavaVM
。这样做的好处是以后不管是使用哪种语言进行编译的,结果都是使用相同的变量
一个小例子
#define MAX 100
int main(){
int i = 99;
if(i < MAX){
printf("i小于MAX");
}
}
定义一个宏常量MAX
,他没有类型,只是完成替换操作
宏函数
#define
指令不仅可以预定义常亮,而且可以预定义函数,其本质也是进行替换,替换掉一些名字非常长的函数名
小例子
#include<stdio.h>
void _jni_define_function_read(){
printf("read方法");
}
void _jni_define_function_write(){
printf("write方法");
}
#define jin(NAME) _jni_define_function_##NAME()
int main(){
//调用jni方法,执行的是_jni_define_function_read方法
jni(read);
return 0;
}
这是一个类似于打印Android Log日志的例子
#include<stdio.h>
#define LOG(LEVE,FORMAT,...) printf(LEVE);printf(FORMAT,##__VA_ARGS__);
#define LOGI(FORMAT,...) LOG("INFO:",FORMAT,__VA_ARGS__);
#define LOGE(FORMAT,...) LOG("ERROR:",FORMAT,__VA_ARGS__);
#define LOGW(FORMAT,...) LOG("WARN:",FORMAT,__VA_ARGS__);
int main(){
LOG("INFO:","%s","日志信息\n");
LOGI("%s","自定义日志,日志信息\n");
LOGE("%s","自定义日志,错误信息\n");
LOGW("%s","自定义日志,警告信息\n");
return 0;
}