我试图将FFmpeg AVDictionary结构从一个函数返回到另一个函数。我写了以下两个函数:
int get_p_metadata(State **ps, AVDictionary *metadata) {
printf("get_p_metadata\n");
State *state = *ps;
if (!state || !state->pFormatCtx) {
return FAILURE;
}
metadata = NULL;
av_dict_copy(&metadata, state->pFormatCtx->metadata, 0);
printf("count in get_p_metadata %d\n", metadata->count);
return SUCCESS;
}
int get_metadata(State **ps) {
printf("get_metadata\n");
AVDictionary m;
get_p_metadata(ps, &m);
printf("count in get_metadata %d\n", (&m)->count);
return SUCCESS;
}
代码编译并运行但是当我调用get_metadata
函数时,生成的输出是:
count in get_p_metadata 12
count in get_metadata 2073109240
有人可以解释为什么每次运行此代码时count
的值会从12变为随机值吗?一旦get_p_metadata
函数返回,为什么不保留12的值?我该如何解决这个问题?
更新:
此解决方案有效(感谢Cornstalks实际阅读FFmpeg文档和 链接答案):
int get_p_metadata (State **ps, AVDictionary **metadata) {
printf("get_p_metadata\n");
State *state = *ps;
if (!state || !state->pFormatCtx) {
return FAILURE;
}
av_dict_copy(metadata, state->pFormatCtx->metadata, 0);
return SUCCESS;
}
int get_metadata(State **ps, AVDictionary *metadata) {
printf("get_metadata\n");
AVDictionary *m = NULL;
get_p_metadata (ps, &m);
printf("count in get_metadata %d\n", m->count);
return SUCCESS;
}
答案 0 :(得分:3)
实际上,在您的get_p_metadata()
中,您有一个参数AVDictionary *metadata
。
您可以将其视为get_p_metadata()
中的局部变量。
因此,&metadata
将引用局部变量,而不是m
中的get_metadata()
变量。
在get_p_metadata()
开始时,metadata
设置为m
的地址,然后将其重置为NULL。
您应该尝试以下方法:
int get_metadata (State **ps)
{
AVDictionary *m = NULL;
get_p_metadata (ps, &m);
av_dict_free (&m);
return SUCCESS;
}
int get_p_metadata (State **ps, AVDictionary **metadata)
{
/* ... */
av_dict_copy (metadata, state->pFormatCtx->metadata, 0);
/* ... */
}
这样,如果av_dict_copy()
为AVDictionary
,*metadata
将为NULL
分配内存,这是现在的初始值。
最后av_dict_free()
将释放字典中使用的内存。
答案 1 :(得分:2)
您从两个语句中得到不同的答案,因为它们是打印不同对象的字段。虽然get_metadata()
将&m
传递给get_p_metadata()
,但该函数完全忽略了传递的值,并将参数值重新分配给NULL
。坦率地说,我很惊讶你没有得到段错误。
我认为设置metadata = NULL
的目的是创建一个新的元数据对象,但是接收指向该新元数据对象的指针的局部变量与传递给该函数的参数之间没有任何联系。
也许你想要
int get_p_metadata(State **ps, AVDictionary **metadata) {
...
}
和
int get_metadata(State **ps) {
printf("get_metadata\n");
AVDictionary *m;
get_p_metadata(ps, &m);
printf("count in get_metadata %d\n", m->count);
// NOTE: *m was dynamically allocated and needs to be cleaned up or returned
return SUCCESS;
}
答案 2 :(得分:1)
根据av_dict_copy的声明:第一个参数“dst”是指向AVDictionary结构的指针。如果* dst为NULL,则此函数将为您分配一个结构并将其放入* dst
对于你的代码,你不应该将“元数据”分配给NULL,因为它已经指向AVDictionary结构,那么它应该没问题。
如果metedata为NULL,则表示av_dict_copy创建一个新的AVDictionary结构并更改其中的值,而get_metadata(State ** ps)中定义的结构保持不变,因此您可以获得任意的vaules。
答案 3 :(得分:-1)
这些陈述中有什么意义?!
metadata = NULL;
av_dict_copy(&metadata, state->pFormatCtx->metadata, 0);
如果将指针传递给对象m
作为第二个函数的参数
AVDictionary m;
get_p_metadata(ps, &m);
然后你似乎要使用它的值或对象本身。否则传递指针是没有意义的。
答案 4 :(得分:-1)
此代码deosnt有意义
metadata = NULL;
av_dict_copy(&metadata, state->pFormatCtx->metadata, 0);
你传入了一个我想要更新的元数据对象的指针。现在将该指针设置为null,调用一个更新该指针的函数。由于我们无法看到你的其他功能很难知道你的意图所以我不能建议修复
答案 5 :(得分:-1)
在调用metadata
之前,您将av_dict_copy
设置为空指针。我想知道为什么它甚至可以工作,并假设av_dict_copy
做了一些不同于你预期的事情(即设置一个值为AVDictionary *,其地址作为第一个参数传递)。无论哪种方式,您都失去了与本地AVDictionary m
的连接,而2073109240只是内存中的一些随机值。