經過FFMPEG代碼學習函數指針和指針函數

函數指針和指針函數介紹

函數指針和指針函數一直在工做中會用到,如今mark下。部份內容是參考其餘人的總結。ide

1. 函數指針是指向函數的指針變量,即本質是一個指針變量。

 int (*f) (int x); /* 聲明一個函數指針 */函數

 f=func; /* 將func函數的首地址賦給指針f */spa

指向函數的指針包含了函數的地址,能夠經過它來調用函數。指針

聲明格式以下:
    類型說明符 (*函數名)(參數)
    其實這裏不能稱爲函數名,應該叫作指針的變量名。這個特殊的指針指向一個返回整型值的函數。指針的聲明類型和它指向函數的聲明保持一致。
     指針名和指針運算符外面的括號改變了默認的運算符優先級。若是沒有圓括號,就變成了一個返回整型指針的函數的原型聲明。
    例如:
        void (*fptr)();
    把函數的地址賦值給函數指針,能夠採用下面兩種形式:
        fptr=&Function;
        fptr=Function;
    取地址運算符&不是必需的,由於單單一個函數標識符就標號表示了它的地址,若是是函數調用,還必須包含一個圓括號括起來的參數表。
    能夠採用以下兩種方式來經過指針調用函數:
        x=(*fptr)();
        x=fptr();code

在FFMPEG 3.2 版本中找到一個函數指針:orm

/**
     * Read the format header and initialize the AVFormatContext
     * structure. Return 0 if OK. 'avformat_new_stream' should be
     * called to create new streams.
     */
    int (*read_header)(struct AVFormatContext *);

 

定義函數flv_read_header();ip

static int flv_read_header(AVFormatContext *s)
{
    FLVContext *flv = s->priv_data;
    int offset;

    avio_skip(s->pb, 4);
    avio_r8(s->pb); // flags

    s->ctx_flags |= AVFMTCTX_NOHEADER;

    offset = avio_rb32(s->pb);
    avio_seek(s->pb, offset, SEEK_SET);
    avio_skip(s->pb, 4);

    s->start_time = 0;
    flv->sum_flv_tag_size = 0;
    flv->last_keyframe_stream_index = -1;

    return 0;
}

 把函數的地址賦值給函數指針:get

AVInputFormat ff_flv_demuxer = {
    .name           = "flv",
    .long_name      = NULL_IF_CONFIG_SMALL("FLV (Flash Video)"),
    .priv_data_size = sizeof(FLVContext),
    .read_probe     = flv_probe,
    .read_header    = flv_read_header,
    .read_packet    = flv_read_packet,
    .read_seek      = flv_read_seek,
    .read_close     = flv_read_close,
    .extensions     = "flv",
    .priv_class     = &flv_class,
};

 

經過指針調用函數:input

int avformat_open_input(AVFormatContext **ps, const char *filename,
                        AVInputFormat *fmt, AVDictionary **options)
{
... ...
    if (!(s->flags&AVFMT_FLAG_PRIV_OPT) && s->iformat->read_header)
        if ((ret = s->iformat->read_header(s)) < 0)
            goto fail;
... ...
}

 

總結:

函數指針本質上是一個指針變量,能夠經過它來調用函數原型

 

2. 指針函數是指帶指針的函數,即本質是一個函數。函數返回類型是某一類型的指針。

     類型標識符    *函數名(參數表)

      int *f(x,y);

首先它是一個函數,只不過這個函數的返回值是一個地址值。函數返回值必須用同類型的指針變量來接受,也就是說,指針函數必定有函數返回值,並且,在主調函數中,函數返回值必須賦給同類型的指針變量。

表示:

float *fun();

float *p;

p = fun(a);

 

在FFMPEG 3.2 版本中找到一個指針函數:

static char *get_ost_filters(OptionsContext *o, AVFormatContext *oc,
                             OutputStream *ost)
{
    AVStream *st = ost->st;

    if (ost->filters_script && ost->filters) {
        av_log(NULL, AV_LOG_ERROR, "Both -filter and -filter_script set for "
               "output stream #%d:%d.\n", nb_output_files, st->index);
        exit_program(1);
    }

    if (ost->filters_script)
        return read_file(ost->filters_script);
    else if (ost->filters)
        return av_strdup(ost->filters);

    return av_strdup(st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO ?
                     "null" : "anull");
}


 

//定義指針變量
char *avfilter;

//函數返回值指向指針變量
avfilter = get_ost_filters(o, oc, ost);

 

總結:

指針函數:本質上是函數,返回值爲指針變量。

相關文章
相關標籤/搜索