预编译
C语言执行的流程
1.编译:形成目标代码(.obj)
2.连接:将目标代码与C函数库连接合并,形成最终的可执行文件
3.执行
预编译(预处理),为编译做准备工作,完成代码文本的替换工作
头文件告诉编译器有这样一个函数,连接器负责找到这个函数的实现
头文件只包含一次,防止重复引用:
1.#ifndef #define #endif组合使用(老版本)
2.#pragma once
define指令
1.定义标示
ifdef __cplusplus 标识支持C++语法
防止文件重复引入
2.定义常数(便于修改与阅读)
define MAX 100
3.定义“宏函数”
define jni(NAME) dn_com_jni_##NAME();NAME是参数,对于dn_com_jni_read函数来说,NAME就是read
//webrtc JNI函数名称很长,也是JOW宏函数缩短函数名称
void dn_com_jni_read(){
}
JNI(Java Native Interface)(Windows下)
Java调用C/C++,C/C++调用Java的一套API
1.编写native方法
2.javah命令,生成.h头文件。
3.复制.h头文件到CPP工程中
4.复制jni.h和jni_md.h文件到CPP工程中(去jdk安装目录里可以找到这两个.h文件)
5.实现.h头文件中声明的函数(C的函数名称:Java_完整类名_函数名)
#include "jni.h"
/* Header for class com_ccg_jni_JniTest */
#ifndef _Included_com_ccg_jni_JniTest
#define _Included_com_ccg_jni_JniTest
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_ccg_jni_JniTest
* Method: getStringFromC
* Signature: ()V
*/
JNIEXPORT jstring JNICALL Java_com_ccg_jni_JniTest_getStringFromC
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
C语言
#include "com_ccg_jni_JniTest.h"
//函数实现
JNIEXPORT jstring JNICALL Java_com_ccg_jni_JniTest_getStringFromC
(JNIEnv *env, jclass jcls){
//JNIEnv 结构体指针
//env二级指针
//代表Java运行环境,调用Java中的代码
//简单的实现
//将C的字符串转为一个java字符串
return (*env)->NewStringUTF(env,"C String");
}
C++
#include "com_ccg_jni_JniTest.h"
JNIEXPORT jstring JNICALL Java_com_ccg_jni_JniTest_getStringFromC
(JNIEnv *env, jclass jcls){
//JNIEnv 在C++中就是一个结构体的别名
//env 在C++中一个结构体的一级指针
return env->NewStringUTF("C String");
}
6.生成dll文件(动态库,最终文件不包含动态库,.a静态库包含在最终文件里)
7.配置dll文件所在目录到环境变量(或者copy到工程根目录下)
8.重启Eclipse
分析JNIEnv
在C中:
JNIEnv 结构体指针别名
env二级指针
在C++中:
JNIEnv 是一个结构体的别名
env 一级指针
1.为什么需要传入JNIEnv,函数执行过程中需要JNIEnv
2.C++为什么没有传入? 因为C++this就代表了JNIEnv
3.C++只是对C的那一套进行的封装,给一个变量赋值为指针,这个变量是二级指针(把指针赋值给指针)
简写JNIEnv
//JNIEnv结构体的指针别名
typedef struct JNINativeInterface_* JNIEnv;
//结构体
struct JNINativeInterface_ {
char* (*NewStringUTF)(JNIEnv*, char*);
};
//函数实现
char* NewStringUTF(JNIEnv* env, char* str){
//在NewStringUTF执行过程,仍然需要JNIEnv
return str;
}
void main(){
//实例化结构体
struct JNINativeInterface_ struct_env;
struct_env.NewStringUTF = NewStringUTF;
//结构体指针
JNIEnv e = &struct_env;
//结构体的二级指针
JNIEnv *env = &e;
//通过二级指针调用函数
char* str = (*env)->NewStringUTF(env,"abc");
}
网友评论