随着直播领域、图片处理、流媒体等应用的房展,NDK在Android 开发中的地位也越来越重要,于是决定写一个专题关于NDK的开发,主要从最基础的C语言讲起,接着是用Android通过NDK 输出helloworld,到后期还会有一些图片处理、音频处理的内容,由于工作比较忙,可能不定期更新。你可以催我,但是不可以骂我。
恩,就这样。
注:本文与JNI\NDK无关,只是先介绍C的常见用法,方便之后的NDK开发,如果你对C很熟练,本文对你的作用不是很大,当然,你也可以看看,权当复习,如有不对的地方,请指出。
在了解NDK之前,我们先了解JNI(Java Native Interface)java 原生接口,通过JNI 可以实现JAVA与C的交互
JNI具体是什么:
这个协议用来沟通java代码和外部的本地代码(c/c++).
通过这个协议,java代码就可以调用外部的c/c++代码
外部的c/c++代码也可以调用java代码
为什么要进行
首先,Java语言提供的类库无法满足要求,且在数学运算,实时渲染的游戏上,音视频处理等方面上与C/C++相比效率稍
其次,Java语言无法直接操作硬件,C/C++代码不仅能操作硬件而且还能发挥硬件最佳
最后,使用Java调用本地的C/C++代码所写的库,省去了重复开发的麻烦,并且可以利用很多开源的库提高程序效率。
接下来,我将会介绍一些C语言的常用操作:
C语言的常用操作
什么是指针
指针就是地址,地址就是指针
地址就是内存单元的编号
指针变量是存放地址的变量
指针和指针变量是两个不同的概念
但是要注意: 通常我们叙述时会把指针变量简称为指针,实际它们含义并不一样
举个例子
#include <stdio.h>
#include <stdlib.h>
main() //入口函数
{
int *p;// p是变量的名字,*p是该地址对应的值,p存放了对应的地址
int i = 3;
p = &i;//把i的地址传给p
printf("p=%d\n",*p);
}
代码块中,把i的地址传给了p,*p为该地址块的值。
打印结果
通过指针,实现一个简单的交换运算
C和java 很相似,先写一个函数,然后在main()函数入口中写入参数,调用函数,代码如下:
void changNum(int i,int j){
int k = j;
j = i;
i = k;
}
main(){
int a = 3;
int b = 5;
changNum(3,5);
printf("a=%d\nb=%d\n",a,b);
}
我们打印下结果:
是不是很奇怪,我们分明调用了函数,交换了参数,但是打印出的结果依然没变。
这正是C语言的独特之处——指针,因为我们传入的参数他们指向的依然是同一个地址的值。正确的做法是,在函数的形参中传入地址值,通过地址交换。
正确代码如下:
void changNum(int *i,int *j){
int k = *j;
*j = *i;
*i = k;
}
main(){
int a = 3;
int b = 5;
changNum(&a,&b);
printf("a=%d\nb=%d\n",a,b);
}
打印结果:
指针函数
在C中,每一个函数都有一个对应的地址块,可以用前面调用指针的方法,通过指针的地址进行函数的操作。
示例代码:
int add(int x , int y){
return x+y;
}
main()
{
int (*hanshu) (int x, int y); //定义一个函数的指针的声明 名字叫hanshu 返回值 int 接受参数两个int
hanshu = add;
printf("result=%d\n", hanshu(2,6));
}
打印结果
二级指针:
二级指针就是指针的指针。
在C中,每个值都有一个对应的地址,但是如果该地址也作为一个值进行操作,则这个值就也需要一个内存空间来存放,这个内存空间的值就是二级指针。
二级指针例子:
int *q; //定义一个一级指针变量,它指向一个普通变量(即它存的是一个变量的地址)
int **p; //定义一个二级指针变量,它指向一个指针变量(它存的也是一个变量地址,只不过是一个指针变量的地址)
int s;
q = &s; //q中存的是整型变量s的地址,所以q是一级指针
p = &q; //p中存的是一级指针q的地址,所以p是二级指针
示例代码:
main(){
int **p;
int *q;
int i = 5;
q = &i;
p = &q;
**p = 3;
printf("%d\n",i);
}
打印结果:
上例中,i 为一个普通参数,值为5,q 存放的是i的地址,p存放的是q的地址,所以**p对应的值就是q的地址对应的值,q存放i的地址,所以**p 就是i的值
结构体:
结构体和Java 中的类用法和作用都是十分相似,在一个结构体重定义了该结构体需要用到的参数。
例子:
struct Person{
int age;
float height;
char job;//c中没有String 类型,字符串通常存放在char[]中
};
main(){
struct Person p = {18,180,'i'};
printf("job is %c\n height is %f\n age is %d\n ",p.job,p.height,p.age);
}
打印结果
结构体指针:
指向结构体的指针,通过-> 操作获取结构体中的值
示例代码:
struct Person{
int age;
float height;
char job;//c中没有String 类型,字符串通常存放在char[]中
};
main(){
struct Person person = {18,180,'i'};
struct Person *p;
p = &person;
// p->age; p指向结构体中age变量,即(*p).age;
printf("age is %d\n",p->age);
}
打印结果