简体   繁体   中英

Deciphering Mangled C++ names $$F

I have the following function call in my unmanaged c++ class:

_pUserApi = CThostFtdcMdApi::CreateFtdcMdApi();

The compiler seems to be generating this symbol:

?CreateFtdcMdApi@CThostFtdcMdApi@@$$FSAPEAV1@PEBD_N1@Z

But when I do a dumpbin on the .lib file I am linking with I see this symbol:

?CreateFtdcMdApi@CThostFtdcMdApi@@SAPEAV1@PEBD_N1@Z

The difference is the first one has an additional $$F in it.

Are there compiler options that would account for this difference?... is there any kind of reference to decipher the mangling?

Note: this is an x64 lib file (and I'm compiling with x64 chosen.

Full Error:

Error   LNK2028 unresolved token (0A000021) 
"public: static class CThostFtdcMdApi * __cdecl CThostFtdcMdApi::CreateFtdcMdApi(char const *,bool,bool)" 
(?CreateFtdcMdApi@CThostFtdcMdApi@@$$FSAPEAV1@PEBD_N1@Z) 
referenced in function "public: void __cdecl CTPMarketData::Start(char const *,char const *,char const *,char const *)" 
(?Start@CTPMarketData@@$$FQEAAXPEBD000@Z)
CTPLib_cpp

Full DumpBin:

  61C __IMPORT_DESCRIPTOR_thostmduserapi
  862 __NULL_IMPORT_DESCRIPTOR
  9A0 thostmduserapi_NULL_THUNK_DATA
  D94 ?CreateFtdcMdApi@CThostFtdcMdApi@@SAPEAV1@PEBD_N1@Z
  D94 __imp_?CreateFtdcMdApi@CThostFtdcMdApi@@SAPEAV1@PEBD_N1@Z
  E2C ?GetApiVersion@CThostFtdcMdApi@@SAPEBDXZ
  E2C __imp_?GetApiVersion@CThostFtdcMdApi@@SAPEBDXZ
  C0E ??1CThostFtdcMdApi@@IEAA@XZ
  C0E __imp_??1CThostFtdcMdApi@@IEAA@XZ
  B8E ??0CThostFtdcMdApi@@QEAA@XZ
  B8E __imp_??0CThostFtdcMdApi@@QEAA@XZ
  B08 ??0CThostFtdcMdApi@@QEAA@AEBV0@@Z
  B08 __imp_??0CThostFtdcMdApi@@QEAA@AEBV0@@Z
  C8E ??4CThostFtdcMdApi@@QEAAAEAV0@AEBV0@@Z
  C8E __imp_??4CThostFtdcMdApi@@QEAAAEAV0@AEBV0@@Z
  D18 __imp_??_7CThostFtdcMdApi@@6B@

The command line generated by visual studio:

d:\\Program Files(x86)\\Microsoft Visual Studio\\2017\\Enterprise\\VC\\Tools\\MSVC\\14.14.26428\\bin\\HostX86\\x86\\CL.exe / c / AI"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework.NETFramework\\v4.6.1\\" / AI"C:\\Program Files (x86)\\Windows Kits\\10\\References" / AI"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework.NETFramework\\v4.6.1\\Facades\\" / Zi / clr / nologo / W3 / WX - / diagnostics:classic / Od / Oy - / D WIN32 / D _DEBUG / D _WINDLL / D _UNICODE / D UNICODE / EHa / MDd / GS / fp : precise / Zc : wchar_t / Zc : forScope / Zc : inline / Yu"stdafx.h" / Fp"Debug\\CTPLib_cpp.pch" / Fo"Debug\\" / Fd"Debug\\vc141.pdb" / TP / FU"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework.NETFramework\\v4.6.1\\mscorlib.dll" / FU"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework.NETFramework\\v4.6.1\\System.Data.dll" / FU"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework.NETFramework\\v4.6.1\\System.dll" / FU"C:\\Program Files (x86)\\Reference Assembli es\\Microsoft\\Framework.NETFramework\\v4.6.1\\System.Xml.dll" / analyze - / FC / errorReport : prompt / clr : nostdlib AssemblyInfo.cpp CTPMarketData.cpp CTPMarketDataWrapper.cpp CTPSpi.cpp

Microsoft compilers come with an undname utility:

with the $$F:

C:\>undname ?CreateFtdcMdApi@CThostFtdcMdApi@@$$FSAPEAV1@PEBD_N1@Z
Microsoft (R) C++ Name Undecorator
Copyright (C) Microsoft Corporation. All rights reserved.

Undecoration of :- "?CreateFtdcMdApi@CThostFtdcMdApi@@$$FSAPEAV1@PEBD_N1@Z"
is :- "public: static class CThostFtdcMdApi * __ptr64 __cdecl CThostFtdcMdApi::CreateFtdcMdApi(char const * __ptr64,bool,bool)"

without:

c:\>undname ?CreateFtdcMdApi@CThostFtdcMdApi@@SAPEAV1@PEBD_N1@Z
Microsoft (R) C++ Name Undecorator
Copyright (C) Microsoft Corporation. All rights reserved.

Undecoration of :- "?CreateFtdcMdApi@CThostFtdcMdApi@@SAPEAV1@PEBD_N1@Z"
is :- "public: static class CThostFtdcMdApi * __ptr64 __cdecl CThostFtdcMdApi::CreateFtdcMdApi(char const * __ptr64,bool,bool)"

Unfortunately, undname decodes both to the same function signature. Some more digging is in order...

PS: An equivalent tool for GCC is c++filt

So... it did turn out to be the difference between a native library and a CLR library. When the calls were made from withing the CLR library it inserted the $$F into the mangled name, but not when the calls were made from within a native library.

Interestingly... I made a class / function in a native library that created the object... that fixed it... plus I was able to call other member functions from within the CLR library code and that worked!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM