1. 程式人生 > >ffmpeg編譯的靜態連結庫問題

ffmpeg編譯的靜態連結庫問題

安裝了ffmpeg在wince編譯生成dll和.a檔案,但是發現這個.a檔案並不是像win32下面的lib檔案,不能夠直接呼叫,如果直接呼叫會產生error LNK2001: unresolved external symbol __alloca和 error LNK2001: unresolved external symbol ___divdi3以及error LNK2001: unresolved external symbol ___umoddi3,就著三個外部庫檔案呼叫失敗,個人認為只是不同的lib有些東西.a檔案裡面還是沒有的,要能夠讓你的vc能夠使用還是把它生成lib檔案的好,下面結合自己的經驗說說怎麼生成lib檔案,記載csdn上面免得又忘了。

在mingw中已經有這樣的工具了叫做dlltool,但是這個沒有見過,後面在講,下面我們將一種win32的方法,如果我們已經有一個dll(我們可以編譯ffmpeg得到),但是我們沒有lib檔案,怎麼辦?在vc下面有這樣的一個工具,叫做DUMPBIN,這個工具可以把dll匯出def檔案來描述dll的介面,
DUMPBIN VideoDeCoder.dll /EXPORTS /OUT:VideoDeCoder.def

我們可以在vc的bin下面找到這個檔案,但是可能會出現一個問題,提示缺少什麼庫,那麼可以參考
http://blog.csdn.net/kv110/archive/2008/06/16/2553850.aspx,這篇文章裡面說的很清楚,好,現在我們可以執行這個dumpbin
然後我們對我們的dll進行使用,我們的dll有三個avcodec.dll、avformat.dll和avutil.dll,這樣我們可以生成三個def檔案,下
一步就是如何將這三個dll變成lib了。
這個def檔案並不是一個專門lib的def檔案而是有一個dll得來,我們要把它變成lib還要一些修改。
原始檔案
Dump of file C:/Program Files/FFmpeg/avutil.dll

File Type: DLL

Section contains the following exports for avutil.dll

00000000 characteristics
49659AAD time date stamp Thu Jan 08 14:18:21 2009
0.00 version
1 ordinal base
34 number of functions
34 number of names

ordinal hint RVA name

1 0 00001C70 av_add_i
2 1 00002850 av_add_q
3 2 00001F10 av_cmp_i
4 3 00003130 av_crc
5 4 00005080 av_crc04C11DB7
6 5 00005090 av_crc07
7 6 00005060 av_crc8005
8 7 00005070 av_crcEDB88320
9 8 00003000 av_crc_init
10 9 00002940 av_d2q
11 A 00002AB0 av_dbl2ext
12 B 00002E30 av_dbl2int
13 C 00002420 av_div_i
14 D 00002800 av_div_q
15 E 00002D40 av_ext2dbl
16 F 00002F30 av_flt2int
17 10 000024D0 av_i2int
18 11 00002C00 av_int2dbl
19 12 00002CC0 av_int2flt
20 13 00002480 av_int2i
21 14 00001D30 av_log2_i
22 15 00001FF0 av_mod_i
23 16 00001D80 av_mul_i
24 17 000027B0 av_mul_q
25 18 00002510 av_reduce
26 19 000016A0 av_rescale
27 1A 00001980 av_rescale_q
28 1B 000013B0 av_rescale_rnd
29 1C 00001F60 av_shr_i
30 1D 00001CD0 av_sub_i
31 1E 000028C0 av_sub_q
32 1F 00001350 ff_gcd
33 20 00001250 ff_log2_tab
34 21 000011D0 ff_sqrt_tab

Summary

1000 .bss
1000 .data
1000 .edata
1000 .idata
1000 .reloc
3000 .text
變換後的檔案:
LIBRARY "avutil"
DESCRIPTION "avutil"


EXPORTS



av_add_i @1
av_add_q @2
av_cmp_i @3
av_crc @4
av_crc04C11DB7 @5
av_crc07 @6
av_crc8005 @7
av_crcEDB88320 @8
av_crc_init @9
av_d2q @10
av_dbl2ext @11
av_dbl2int @12
av_div_i @13
av_div_q @14
av_ext2dbl @15
av_flt2int @16
av_i2int @17
av_int2dbl @18
av_int2flt @19
av_int2i @20
av_log2_i @21
av_mod_i @22
av_mul_i @23
av_mul_q @24
av_reduce @25
av_rescale @26
av_rescale_q @27
av_rescale_rnd @28
av_shr_i @29
av_sub_i @30
av_sub_q @31
1ff_gcd @32
ff_log2_tab @33
ff_sqrt_tab @34


所有的函式放至行首,去掉 "hint" 和 "RVA" 資料,留下函式的序號 "ordinal" ,在序號前加上 "@" 符號 形成
"_匯出函式名@引數位元組和 @序號" 此種格式(__stdcall 方式呼叫匯出的函式符號是 "函式名稱@引數位元組和").
最後形成.DEF檔案如下:

使用VC++的LIB工具,帶/DEF:(.def檔名) /MACHINE:IX86(80X86機器),就輸出符合VC++格式的的LIB檔案了. 
EXAMPLE:

LIB /DEF:avutil.def /MACHINE:IX86

時帶上LIB檔案連結;注意的是當有些動態庫DUMPBIN的只有函式名,無"@nn"的引數格式,如C++Builder寫的DLL,輸出就只有函式名
符號,連結時就會報錯: error LNK2002:unresolved external symbol "functionname@nn"
提示程式中引入的函式符號無法識別,這時只要將DEF檔案中相應的函式名稱改為functionname@nn方式,重新建立 LIB,重新連結即可.