编译FFMPEG时,Mac上的g ++链接错误 [英] g++ Linking Error on Mac while compiling FFMPEG

查看:298
本文介绍了编译FFMPEG时,Mac上的g ++链接错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



test.cpp

  #include< iostream> 
使用命名空间std;
#include< libavcodec / avcodec.h> // required headers
#include< libavformat / avformat.h>
int main(int argc,char ** argv){
av_register_all(); //违规图书馆调用
返回0;
}

当我尝试使用以下命令编译这个命令

  g ++ test.cpp -I / usr / local / include -L / usr / local / lib \ 
-lavcodec -lavformat -lavutil -lz -lm -o test

我收到错误
未定义的符号:
av_register_all(),引用来自:
_main in ccUD1ueX.o
ld:未找到符号
collect2:ld返回1退出状态



有趣的是,如果我有一个等价的c代码,
test.c

  #include < stdio.h中> 
#include< libavcodec / avcodec.h>
#include< libavformat / avformat.h>
int main(int argc,char ** argv){
av_register_all();
return 0;
}

gcc编译它很好

  gcc test.c -I / usr / local / include -L / usr / local / lib \ 
-lavcodec -lavformat -lavutil -lz -lm - o test

我正在使用Mac OS X 10.6.5

  $ g ++ --version 
i686-apple-darwin10-g ++ - 4.2.1(GCC)4.2.1(Apple Inc. build 5664)
$ gcc --version
i686-apple-darwin10-gcc-4.2.1(GCC)4.2.1(Apple Inc. build 5664)

FFMPEG的libavcodec,libavformat等是C库,我已经在我的机器上构建了它们,如:

  ./ configure --enable-gpl --enable-pthreads --enable-shared \ 
--disable-doc --enable-libx264
make&& sudo make install

正如所料,libavformat确实包含符号av_register_all

  $ nm /usr/local/lib/libavformat.a | grep av_register_all 
0000000000000000 T _av_register_all
00000000000089b0 S _av_register_all.eh

我很倾向相信g ++和gcc对我机器上的库有不同的看法。 g ++不能拿起正确的库。任何线索?

解决方案

这可能是因为 av_register_all externC块中,因此当前向声明由C ++编译器解释时,它的名称被破坏。尝试将您的代码更改为:

  #include< iostream> 
使用命名空间std;
externC{
#include #include< libavformat / avformat.h>
}
int main(int argc,char ** argv){
av_register_all(); //违规图书馆调用
返回0;
}

C ++编译器使用的名称允许覆盖相同的函数使用不同的参数,但不由C编译器(不提供函数覆盖)执行。



通常,用C编写的标题可以包含在C ++中文件应具有以下结构,以防止发生此类错误。您应该通知ffmpeg开发人员修改其代码:

  //标准包括保护
#ifndef INCLUDED_AVCODEC_H
#define INCLUDED_AVCODEC_H

//防止包含C ++文件
#ifdef __cplusplus
externC{
#endif

// C代码
// ....

//关闭防止包含C ++文件的保护
#ifdef __cplusplus
}
#endif
#endif

:我刚刚发现在 FFmpeg wiki中提到了这一点


g++ on Snow Leopard is throwing linking errors on the following piece of code

test.cpp

#include <iostream>
using namespace std;
#include <libavcodec/avcodec.h>    // required headers
#include <libavformat/avformat.h>
int main(int argc, char**argv) {
    av_register_all();             // offending library call
    return 0;
}

When I try to compile this using the following command

g++ test.cpp -I/usr/local/include -L/usr/local/lib \
-lavcodec -lavformat -lavutil -lz -lm -o test

I get the error Undefined symbols: "av_register_all()", referenced from: _main in ccUD1ueX.o ld: symbol(s) not found collect2: ld returned 1 exit status

Interestingly, if I have an equivalent c code, test.c

#include <stdio.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
int main(int argc, char**argv) {
    av_register_all();
    return 0;
}

gcc compiles it just fine

gcc test.c -I/usr/local/include -L/usr/local/lib \
-lavcodec -lavformat -lavutil -lz -lm -o test

I am using Mac OS X 10.6.5

$ g++ --version
i686-apple-darwin10-g++-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5664)
$ gcc --version
i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5664)

FFMPEG's libavcodec, libavformat etc. are C libraries and I have built them on my machine like thus:

./configure --enable-gpl --enable-pthreads --enable-shared \
--disable-doc --enable-libx264
make && sudo make install

As one would expect, libavformat indeed contains the symbol av_register_all

$ nm /usr/local/lib/libavformat.a | grep av_register_all
0000000000000000 T _av_register_all
00000000000089b0 S _av_register_all.eh

I am inclined to believe g++ and gcc have different views of the libraries on my machine. g++ is not able to pick up the right libraries. Any clue?

解决方案

This is probably because the av_register_all function is not in an extern "C" block and thus when the forward declaration is interpreted by the C++ compiler, it's name is mangled. Try to change your code to:

#include <iostream>
using namespace std;
extern "C" {
#include <libavcodec/avcodec.h>    // required headers
#include <libavformat/avformat.h>
}
int main(int argc, char**argv) {
    av_register_all();             // offending library call
    return 0;
}

The name mangling is used by the C++ compilers to allow override of the same function with differents arguments, but is not performed by C compilers (which do not offer function overriding).

Generally, the headers that are written in C and can be included in C++ file should have the following structure to prevent such bugs to occurs. You should probably inform the ffmpeg developpers to have their code modified:

// Standard includes guards
#ifndef INCLUDED_AVCODEC_H
#define INCLUDED_AVCODEC_H

// Protection against inclusion by a C++ file
#ifdef __cplusplus
extern "C" {
#endif

// C code
// ....

// Closing the protection against inclusion by a C++ file
#ifdef __cplusplus
}
#endif
#endif

[Edit]: I just found out that this is mentioned on FFmpeg wiki.

这篇关于编译FFMPEG时,Mac上的g ++链接错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆