DLL中調用約定和名稱修飾(三)
2、C++編譯時函數(非類成員函數)名稱修飾
當函數使用__cdecl調用約定時,編譯器進行以下工作:
1.以?標識函數名的開始,后跟函數名;
2.函數名后面以@@YA標識開始,后跟返回值和參數表;
3.當函數的返回值或者參數與C++類無關的時候,返回值和參數表以下列代號表示:
B:const
D:char
E:unsigned char
F:short
G:unsigned short
H:int
I:unsigned int
J:long
K:unsigned long
M:float
N:double
_N:bool
PA:指針(*,后面的代號表明指針類型,如果相同類型的指針連續(xù)出現(xiàn),以0
代替,一個0代表一次重復)
PB:const指針
AA:引用(&)
AB:const引用
U:類或結構體
V:Interface(接口)
W4:enum
X:void
4、@@YA標識之后緊跟的是該函數的返回值類型,其后依次為參數的數據類型,指針標識在其所指數據類型前。當函數的返回值或者參數與C++類無關的時候,其處理符合本條規(guī)則,否則按照5、6規(guī)則處理;
5、當函數返回值為某個類或帶有const性質的類的時候,返回值的命名為:?A/?B+V+類名+@@(不帶加號)。當函數返回值為某個類的指針/引用或者帶有const性質的類的指針/引用的時候,返回值的命名為:PA/AA或者PB/AB+V+類名+@@(不帶加號);
6、函數參數為某個類的時候,并且該參數所使用的類曾經出現(xiàn)過的話(也就是與函數返回值所使用的類相同或者與前一個參數使用的類相同),則該參數類型格式為:V+1+@(不帶加號)。如果該參數所使用的類沒有出現(xiàn)過的話,則該參數類型格式為:V+類名+@@(不帶加號)。函數參數為某個類的指針/引用或者帶有const性質指針/引用的時候,則該參數類型格式是在上述格式的基礎上在V前面加上代表指針/引用類型或者帶有const性質指針/引用類型的標識符(PA/AA或PB/AB);
7、參數表后以@Z標識整個名字的結束,如果該函數無參數,則以Z標識結束。
當函數使用__stdcall調用約定時,編譯器所做工作的規(guī)則同上面的__cdecl調用約定,只是參數表的開始標識由上面的@@YA變?yōu)?/span>@@YG。
當函數使用__fastcall調用約定時,編譯器所做工作的規(guī)則同上面的__cdecl調用約定,只是參數表的開始標識由上面的@@YA變?yōu)?/span>@@YI。
3、C++編譯類及其成員函數時名稱修飾
對于導出的C++類,僅能使用__cdecl調用約定。在編譯器編譯過程中,編譯器會對C++類進行處理。如:class __declspec(dllexport) MyClass會被處理為class MyClass & MyClass::operator=(class MyClass const &)。在C++編譯器對C++類進行名稱修飾的時候,編譯器進行以下工作:
1.以?標識函數名的開始,后跟?4+類名;
2.類名后面跟@@QAE標識,對于導出類來說這是固定的;
3.@@QAE后面跟AAV0@ABV0@,即引用類型標識符AA+V+0(重復的類的標識符)+@(不帶加號)和const性質的引用AB+V+ 0(重復的類的標識符)+@(不帶加號);
4.最后以@Z標識整個名字的結束。
對于導出的C++類中的成員函數(非構造函數和析構函數),可以使用不同的調用約定。當導出的C++類中的成員函數使用__cdecl調用約定時,編譯器進行以下工作:
1.以?標識函數名的開始,后跟函數名+@+類名(不帶加號);
2.之后以@@QAE標識開始,后跟返回值和參數表;
3.當函數的返回值或者參數與C++類無關的時候,返回值和參數表以下列代號表示:
B:const
D:char
E:unsigned char
F:short
G:unsigned short
H:int
I:unsigned int
J:long
K:unsigned long
M:float
N:double
_N:bool
PA:指針(*,后面的代號表明指針類型,如果相同類型的指針連續(xù)出現(xiàn),以0
代替,一個0代表一次重復)
PB:const指針
AA:引用(&)
AB:const引用
U:類或結構體
V:Interface(接口)
W4:enum
X:void
4、@@QAE標識之后緊跟的是該函數的返回值類型,其后依次為參數的數據類型,指針標識在其所指數據類型前。當函數的返回值或者參數與C++類無關的時候,其處理符合本條規(guī)則,否則按照5、6規(guī)則處理;
5、當函數返回值為當前類或帶有const性質的當前類的時候,返回值的命名為:?A或?B+V+1+@@(不帶加號)。當函數返回值為當前類的指針/引用或者帶有const性質的當前類的指針/引用的時候,返回值的命名為:PA/AA或PB/AB+V+1+@@(不帶加號);
6、當函數返回值為某個類或帶有const性質的類的時候,返回值的命名為:?A/?B+V+類名+@@(不帶加號)。當函數返回值為某個類的指針/引用或者帶有const性質的類的指針/引用的時候,返回值的命名為:PA/AA或者PB/AB+V+類名+@@(不帶加號);
7、函數參數為某個類的時候,并且該參數所使用的類曾經出現(xiàn)過的話(也就是當前要導出的類、與函數返回值所使用的類相同或者與前一個參數使用的類相同的類),則該參數類型格式為:V+1+@(不帶加號)。如果該參數所使用的類不是當前要導出的類的話,則該參數類型格式為:V+類名+@@(不帶加號)。函數參數為某個類的指針/引用或者帶有const性質指針/引用的時候,則該參數類型格式是在上述格式的基礎上在V前面加上代表指針/引用類型或者帶有const性質指針/引用類型的標識符(PA/AA或PB/AB);
8、參數表后以@Z標識整個名字的結束,如果該函數無參數,則以Z標識結束。
當函數使用__stdcall調用約定時,編譯器所做工作的規(guī)則同上面的__cdecl調用約定,只是參數表的開始標識由上面的@@YA變?yōu)?/span>@@YG。
當函數使用__fastcall調用約定時,編譯器所做工作的規(guī)則同上面的__cdecl調用約定,只是參數表的開始標識由上面的@@YA變?yōu)?/span>@@YI。
4、C++編譯導出數據時名稱修飾
對于導出的數據,僅使用__cdecl調用約定。在C++編譯器對C++類進行名稱修飾的時候,編譯器進行以下工作:
1.以?標識數據的開始,后跟數據名;
2.數據名后面以@@3標識開始,后跟數據類型;
3.當數據類型與C++類無關的時候,數據類型以下列代號表示:
B:const
D:char
E:unsigned char
F:short
G:unsigned short
H:int
I:unsigned int
J:long
K:unsigned long
M:float
N:double
_N:bool
PA:指針(*,后面的代號表明指針類型,如果相同類型的指針連續(xù)出現(xiàn),以0
代替,一個0代表一次重復)
PB:const指針
AA:引用(&)
AB:const引用
U:類或結構體
V:Interface(接口)
W4:enum
X:void
4.如果數據類型是某個類的時候,數據類型的命名為:V+類名+@@(不帶加號)。當數據類型為當前類的指針/引用或者帶有const性質的當前類的指針/引用的時候,數據類型的命名為:PA/AA或PB/AB+V+類名+@@(不帶加號);
5.最后,如果數據類型是const性質,則修飾名以B結尾。如果數據類型是非const性質,則修飾名以A結尾。
================================================================
粉顏色的地方是覺得不準確的地方,關于名稱修飾還有很多東西,但基本上DLL之中也就用到這些,所以對其它未作分析。
---rivershan原創(chuàng)于2004.3.3 5:32