gcc 编译 libavformat 代码,但 g++ 不编译
gcc compiles libavformat code, but g++ does not
为了确定给定文件的视频持续时间,我使用了 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++ 不能正确编译这个程序?
这个错误告诉我们所有我们需要知道的:
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>
}
通常,header 文件中会有 extern "C"
部分。 FFmpeg 项目似乎对此不感兴趣。某些 header 可能包含与 C++ 不兼容的 C 构造,如 FFmpeg ticket #3626 中所述。
如果你 运行 遇到这样的问题,你需要用 C 写一个 shim。
为了确定给定文件的视频持续时间,我使用了 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++ 不能正确编译这个程序?
这个错误告诉我们所有我们需要知道的:
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>
}
通常,header 文件中会有 extern "C"
部分。 FFmpeg 项目似乎对此不感兴趣。某些 header 可能包含与 C++ 不兼容的 C 构造,如 FFmpeg ticket #3626 中所述。
如果你 运行 遇到这样的问题,你需要用 C 写一个 shim。