头文件(.h):
写类的声明(包括类里面的成员和方法的声明)、函数原型、#define常数等,但一般来说不写出具体的实现。
比如下面的ffmpeg的编码的一个头文件avcodec.h
开头
多说一句,这个ifndef是if not define的缩写,就是,如果没有定义,就执行下面的#define,防止编译出错
#ifndef AVCODEC_AVCODEC_H
#define AVCODEC_AVCODEC_H
常数
#define SLICE_FLAG_CODED_ORDER 0x0001 ///< draw_horiz_band() is called in coded order instead of display
#define SLICE_FLAG_ALLOW_FIELD 0x0002 ///< allow draw_horiz_band() with field slices (MPEG2 field pics)
#define SLICE_FLAG_ALLOW_PLANE 0x0004 ///< allow draw_horiz_band() with 1 component at a time (SVQ1)
方法
void av_free_packet(AVPacket *pkt);
结尾
#endif
在开头和结尾处必须按照如上样式加上预编译语句,对于AVCODEC_AVCODEC_H你可以写成任何你想要的名字,但推荐这样写,和文件名保持一致,
源文件(.cpp):
源文件主要写实现头文件中已经声明的那些函数的具体代码。需要注意的是,开头必须#include一下实现的头文件,以及要用到的头文件。那么当你需要用到自己写的头文件中的类时,只需要#include进来就行了。
比如:
#include <libavcodec/avcodec.h>
extern "C"
//返回类型String
jstring
//avcodecinfo为方法名,Java不动,com这一堆就是包名了,MainActivity就是展示的界面了,
Java_com_great_xiaohaihai_myffmpeg_MainActivity_avcodecinfo(
JNIEnv *env, jobject) {
char info[40000] = {0};
av_register_all();
AVCodec *c_temp = av_codec_next(NULL);
while (c_temp != NULL) {
if (c_temp->decode != NULL) {
sprintf(info, "%sdecode:", info);
} else {
sprintf(info, "%sencode:", info);
}
switch (c_temp->type) {
case AVMEDIA_TYPE_VIDEO:
sprintf(info, "%s(video):", info);
break;
case AVMEDIA_TYPE_AUDIO:
sprintf(info, "%s(audio):", info);
break;
default:
sprintf(info, "%s(other):", info);
break;
}
sprintf(info, "%s[%10s]\n", info, c_temp->name);
c_temp = c_temp->next;
}
return env->NewStringUTF(info);
}
.h叫做头文件,它是不能被编译的。“#include”叫做编译预处理指令,可以简单理解成,在1.cpp中的#include”1.h”指令把1.h中的代码在编译前添加到了1.cpp的头部。每个.cpp文件会被编译,生成一个.obj文件,然后所有的.obj文件链接起来你的可执行程序就算生成了。
你要在.h文件中严格区分声明语句和定义语句。好的习惯是,头文件中应只处理常量、变量、函数以及类的声明,变量的定义和函数的实现都应该在源文件.cpp中进行。