【问题标题】:gcc compiles libavformat code, but g++ does not [duplicate]gcc编译libavformat代码,但g++没有[重复]
【发布时间】:2017-03-15 01:41:14
【问题描述】:

为了确定给定文件的视频时长,我使用 libavformat。我的程序如下所示:

#include <stdio.h>
#include <libavformat/avformat.h>
#include <libavutil/dict.h>
int main (int argc, char **argv) {
    AVFormatContext *fmt_ctx = NULL;
    int ret;
    if (argc != 2) {
        printf("usage: %s <input_file>\n", argv[0]);
        return 1;
    }
    av_register_all();
    if ((ret = avformat_open_input(&fmt_ctx, argv[1], NULL, NULL)))
        return ret;
    int64_t duration = fmt_ctx->duration;
    int hours, mins, secs;
    secs  = duration / AV_TIME_BASE;
    mins  = secs / 60;
    secs %= 60;
    hours = mins / 60;
    mins %= 60;
    printf("Duration: %02d:%02d:%02d\n", hours, mins, secs);
    avformat_free_context(fmt_ctx);
    return 0;
}

我的问题是,虽然 gcc 编译代码很好,但 g++ 也没有抱怨,但是创建的目标文件既不能被 gcc 链接,也不能被 g++ 链接。或者更准确地说:

gcc -c duration.c
gcc -o duration duration.o -lavformat
./duration my_movie.mp4

有效。但是这个

g++ -c duration.c # "works" as in "g++ does not complain"
g++ -o duration duration.o -lavformat # (gcc produces the same output after compiling with g++)
duration.o: In function `main':
duration.c:(.text+0x41): undefined reference to `av_register_all()'
duration.c:(.text+0x62): undefined reference to `avformat_open_input(AVFormatContext**, char const*, AVInputFormat*, AVDictionary**)'
duration.c:(.text+0x18c): undefined reference to `avformat_free_context(AVFormatContext*)'
collect2: error: ld returned 1 exit status

不起作用。这使我得出结论,g++ 不会生成可以正确链接的代码(在这种情况下)。

我真的很想用 g++ 来完成这项工作,因为它是一个更大的 c++ 项目的一部分,而且总是不得不用 gcc 来编译使用这个库的文件会有点混乱。有谁知道为什么 g++ 不能正确编译这个程序吗?

【问题讨论】:

  • 可能是名称混淆问题?尝试使用 extern "C" 包装包含
  • 听起来您在名称修改方面遇到了问题。您可以尝试在周围喷洒extern "C"。或者,接受 C 和 C++ 是不同的语言。
  • 为什么你认为 c 代码应该编译为不同的语言?
  • @Olaf:我没有看到任何证据表明 OP 对这里的语言感到困惑。贴出的具体代码是有效的 C++,问题出在 FFmpeg 头文件上。
  • @DietrichEpp: 1) 如果头文件用于 C,则不得使用 C++ 编译器编译它们。 2) 从发布的行中,他尝试将.c 文件编译为 C++(使用 g++)。 C 编译器通常是 gcc,而不是 g++。足以怀疑混淆的证据。

标签: c++ gcc g++ libavformat


【解决方案1】:

这个错误告诉我们我们需要知道的一切:

duration.c:(.text+0x62): undefined reference to `avformat_open_input(AVFormatContext**, char const*, AVInputFormat*, AVDictionary**)'

链接器不会知道参数的类型,除非它认为它是一个 C++ 函数。所以你需要这样做:

extern "C" {
#include <libavformat/avformat.h>
#include <libavutil/dict.h>
}

通常,头文件中会包含extern "C" 部分。 FFmpeg 项目似乎对此不感兴趣。一些标头可能包含与 C++ 不兼容的 C 构造,如 FFmpeg ticket #3626 中所述。

如果遇到此类问题,则需要用 C 编写 shim。

【讨论】:

  • 天哪,这很简单!我以前没有见过这种语言结构,但它确实起到了作用,谢谢!
猜你喜欢
  • 1970-01-01
  • 2017-02-02
  • 1970-01-01
  • 1970-01-01
  • 2020-07-15
  • 1970-01-01
  • 2010-11-03
  • 2015-12-01
  • 1970-01-01
相关资源
最近更新 更多