LINUX.ORG.RU

Компиляция программы на C++ с использованием статических библиотек

 , ,


0

2

Всем привет. Есть необходимость поработать с видеопотоком, кодированным по стандарту h264. Решил использовать библиотеки проекта ffmpeg для этой цели. Собрал ffmpeg по мануалу с официального сайта, статические библиотеки (файлы с расширением .a) легли в /home/username/ffmpeg_build/lib. Решил попробовать скомпилировать кусочек кода из вот этой статьи.

Мой учебный вариант:

#include <iostream>

#ifdef __cplusplus
extern "C"
{
	void av_register_all(void);
	void avcodec_register_all(void);
	unsigned avcodec_get_edge_width(void);
	const char * avcodec_license(void);
	struct AVFormatContext;
	struct AVInputFormat;
	struct AVDictionary;
	int avformat_open_input(AVFormatContext **, const char *, AVInputFormat *, AVDictionary **);
	int avformat_find_stream_info(AVFormatContext *, AVDictionary **);
	void av_dump_format(AVFormatContext *, int, const char*, int);
}
#endif

int main(int argc, char* argv[])
{
	if (argc < 2)
	{
		std::cout << "usage: %s filename" << std::endl;
		return 0;
	}
	av_register_all();
	int error;
	const char* filename = argv[1];
	struct AVFormatContext* format_context = nullptr;
	error = avformat_open_input(&format_context, filename, nullptr, nullptr);
	if (error < 0)
	{
		std::cout << "ffmpeg: unable to open " << argv[1] << std::endl;
		return -1;
	}
	error = avformat_find_stream_info(format_context, nullptr);
	if (error < 0)
	{
		std::cout << "ffmpeg: unable to find stream info" << std::endl;
		return -1;
	}
	std::cout << format_context->video_codec->name << std::endl; // маты компилятора
	return 0;
}

Компилирую так:

g++ -L /home/username/ffmpeg_build/lib -o prog prog.cpp -lavformat -lavcodec -lavutil -lswresample -lmp3lame -ltheora -lopus /usr/lib/x86_64-linux-gnu/libtheora.a -lvpx -lvorbis -lvorbisenc -lx264 -lva -logg -pthread -std=c++11 -lz

И компилятор матерится:

prog.cpp:42:29: error: invalid use of incomplete type ‘struct AVFormatContext’
  std::cout << format_context->video_codec->name << std::endl;
                             ^
prog.cpp:10:9: error: forward declaration of ‘struct AVFormatContext’
  struct AVFormatContext;

Как я понимаю, это связано с тем, что я типа обращаюсь к несуществующему с точки зрения компилятора полю структуры format_context.

В каталоге ffmpeg_build есть, кроме каталога со статическими либами (lib), еще каталог с заголовочными файлами .h, называющийся include. В одном из которых как раз есть определения структур и прочих типов.

Может мне нужно как-то эти заголовочные файлы прикрутить к программе? Но как именно, я не понимаю. Если указывать их в стиле #include <libavformat/avformat.h> и добавить в g++ опцию -I /home/username/ffmpeg_build/include, то компилятор уже ругается на повторные объявления функций в секции extern "C". Если эти объявления оттуда убрать, то компилятор перестает «видеть» вызываемые функции, не взирая на то, что через -l перечислены статические библиотеки, содержащие эти функции.

В общем, как сделать так, чтобы все закомпилилось, имея на руках нужные хедеры и статические либы? :-)


Естественно тебе нужно подключать заголовочные файлы, #include <libavformat/avformat.h> и -I/home/username/ffmpeg_build/include. Без этого код даже не скомпилируется, и до линковки и библиотек дело даже не дойдёт. Далее показывай ошибки.

slovazap ★★★★★
()

компилятор уже ругается на повторные объявления функций в секции extern «C».

Так а не надо самому ничего объявлять, блок extern "C" со всем содержимым нужно удалить, а #include добавить.

xaizek ★★★★★
()
extern "C"
{
#include "my_c_lib.h"
}
DELIRIUM ☆☆☆☆☆
()

Уже всё рассказали до меня, но я подытожу: заголовочные файлы ffmpeg нужно заворачивать в extern «C»:

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

m0rph ★★★★★
()
Последнее исправление: m0rph (всего исправлений: 1)

Большое спасибо всем отписавшимся, добавил нужные include'ы в секцию extern "C" (а объявления функций и структур убрал) и заработало как надо.

s3rjke
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.