DLL导出函数名称改编的解决方法
***************************************************
更多精彩,歡迎進(jìn)入:http://shop115376623.taobao.com
***************************************************
1.DLL編譯后導(dǎo)出函數(shù)名稱改變
?
在編寫一個(gè)DLL后,為了能被別的程序調(diào)用,需要將被使用的函數(shù)導(dǎo)出;
但是一般的編譯器都會(huì)將到處函數(shù)名稱改變;
例如:在VC中新建一個(gè)空的win32 dll工程,然后添加下面的文件;
[cpp]?view plaincopy
[cpp]?view plaincopy
?
編譯以后,得到dll1.dll與dll1.lib;使用Dumpbin.exe或者是Depends工具查(dll查看器)看發(fā)現(xiàn),
dll1.dll中的到處函數(shù)名稱為:?add@@YAHH@Z?;這個(gè)新的函數(shù)名稱是C++編譯器對(duì)add函數(shù)的名稱進(jìn)行了改變,
而且不同的編譯器的改編規(guī)則也不一樣,這就導(dǎo)致在通過add函數(shù)名對(duì)函數(shù)進(jìn)行調(diào)用時(shí)無法找到add函數(shù),
因?yàn)榇藭r(shí)add的函數(shù)名稱已經(jīng)被改編;
?
2.限定導(dǎo)出函數(shù)名稱
?
為了解決C與C++能在不同編譯器之間正常調(diào)用DLL,所以我們希望DLL在編譯過程中不要對(duì)函數(shù)名稱進(jìn)行改編;
我們可以在定義導(dǎo)出函數(shù)時(shí),加上限定符 extern "C"
我們把上面的例子修改下:
[cpp]?view plaincopy
?
[cpp]?view plaincopy
我們?cè)俅尉幾g得到dll1.dll,通過工具查看其到導(dǎo)出函數(shù)發(fā)現(xiàn),此時(shí)的add函數(shù)的導(dǎo)出名稱仍然是add;
這樣我們就可以在其他編譯器上直接通過add調(diào)用該函數(shù)了;
?
3.__stdcall關(guān)鍵字將使限定無效
如果我們?cè)诘诙€(gè)的基礎(chǔ)上給函數(shù)加上__stdcall關(guān)鍵字,導(dǎo)出函數(shù)的名稱將仍然被改編;
如果沒有添加__stdcall關(guān)鍵字,那么函數(shù)調(diào)用約定為C調(diào)用約定。如果加了__stdcall標(biāo)準(zhǔn)調(diào)用約定,
就是WINAPI調(diào)用約定,也就是pascal調(diào)用約定,這種約定與C調(diào)用約定不一樣。
[cpp]?view plaincopy
?
[cpp]?view plaincopy
重新編譯,然后通過工具查看DLL的導(dǎo)出函數(shù),發(fā)現(xiàn)名稱為: _add@8;
也就是說如果函數(shù)的調(diào)用約定發(fā)生變化,即使在聲明時(shí)使用了 extern "C"限定符,函數(shù)名稱仍然會(huì)
改編;
C語言與Delphi的調(diào)用約定是不一樣的,Delphi使用的是pascal調(diào)用約定,如果我們要用C寫一個(gè)DLL供Delphi使用,
那么在導(dǎo)出函數(shù)時(shí)應(yīng)指定其使用標(biāo)準(zhǔn)的函數(shù)調(diào)用約定,但此時(shí) 導(dǎo)出函數(shù)名稱就會(huì)被改編;
?
在這種情況下,我們需要通過一個(gè)稱為模塊定義文件(DEF)的方法解決名稱被改編的問題;
?
在上面例子的基礎(chǔ)上,我們給這個(gè)工程添加一個(gè)后綴為def的文件dll1.def;然后添加如下代碼:
[c-sharp]?view plaincopy
此文件中LIBRARY指定動(dòng)態(tài)鏈接庫(kù)的內(nèi)部名稱,該名稱與生成的動(dòng)態(tài)鏈接庫(kù)名稱要匹配;
EXPORTS下面就是要導(dǎo)出的函數(shù);
如果EXPORTS下的函數(shù)個(gè)數(shù)多時(shí),方式為:
LIBRARY “dlll”
EXPORTS
ADD
SUB
MUL
……
如果導(dǎo)出的函數(shù)名稱與源文件中的函數(shù)名稱不一樣可以通過下面的語法指定導(dǎo)出函數(shù)名稱:
entryname = internalname
?
編譯時(shí),編譯器會(huì)按照def中指定的函數(shù)名稱導(dǎo)出函數(shù);
?
重新編譯,通過工具查看dll1.dll中的導(dǎo)出函數(shù)為add了;
總結(jié)
以上是生活随笔為你收集整理的DLL导出函数名称改编的解决方法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Tomcat8正确配置环境变量详细方法
- 下一篇: 离散数学图灵机文章