原文链接:https://blog.csdn.net/Jammg/article/details/52639936
今天用vs开发ffmpeg突然冒出一个这样的错误
由于程序用到了 avcodec 和 avutil 这两个库,而 av_frame_alloc是属于 avutil这个库的。
以下通过查询头文件,发现 av_frame_alloc 并非属于 avcodec 动态库的函数,那为什么会这样子呢?
我决定再查询一下 avcodec-57.all 和 libavcodec.dll.a,用dumpbin程序:
-
dumpbin -exports avcodec
-57.dll
-
dumpbin -exports libavcodec.dll.a
发现av_frame_alloc 也没有在导入库 和 动态库,那么为什么编译器认定av_frame_alloc要在 avcodec这个库寻找呢?
因为程序build是成功的,我再次查看可执行文件的内容,同样dumpbin :
dumpbin -exports *.exe
可以得出以下内容:
发现,avcodec的函数跑到avutil去 ,avutil的跑到avcodec去。。。。。。。。。。。。。。。。。。。。。。。。
以前在qt平台也用过,怎么没问题,最后。。。
发现程序导入库使用了
#pragma comment(lib, "libavcodec.all.a")
...
经查实:
.dll.a文件的最初用意其实是MinGW下的DLL文件的imp-lib (Import Library),即与VC下DLL文件附带了一个引入库.lib类似。在VC下编程,当要使用DLL文件时,在开发时必须要有.lib文件才能链接通过。.dll.a文件就是这样的作用。
也就是说 ,之前qt用的是mingw,导入dll.a当然没问题了,vs使用的是msvc编译器,导入库是.lib格式的,所以问题就在这里了。
改用:
#pragma comment(lib, "avcodec.lib")
问题解决。
那么,为什么程序可以build成功,生成可执行,只是执行不了呢?
导入库里面只是存储了函数[symbol]的地址,由于dll.a在msvc下不能正常工作,所以出现了链接“错误”,但连接器是不知道的,所以连接出了这种情况。
从这里我们也知道,程序一开始执行,就首先需要将所有用到的dll的函数 转换成 函数的地址,也就是地址重定位!