解密Mangled C ++名称$$ F.

时间:2018-05-10 04:06:21

标签: c++ linker-errors

我的非托管c ++类中有以下函数调用:

_pUserApi = CThostFtdcMdApi::CreateFtdcMdApi();

编译器似乎生成了这个符号:

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

但是当我在.lib文件上执行dumpbin时,我正在链接,我看到了这个符号:

?CreateFtdcMdApi@CThostFtdcMdApi@@SAPEAV1@PEBD_N1@Z

区别在于第一个有额外的$$ F。

是否有可以解释这种差异的编译器选项?...是否有任何类型的参考来破译重整?

注意:这是一个x64 lib文件(我选择编译x64。

完全错误:

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@

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文件(x86)\参考程序集\ 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 Assemblies \ Microsoft \ Framework.NETFramework \ v4.6.1 \ System.Xml.dll" / analyze - / FC / errorReport:prompt / clr:nostdlib AssemblyInfo.cpp CTPMarketData.cpp CTPMarketDataWrapper.cpp CTPSpi.cpp

3 个答案:

答案 0 :(得分:3)

Microsoft编译器带有undname实用程序:

使用$$ 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)"

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)"

不幸的是,undname将两者都解码为相同的函数签名。还有一些挖掘工作正在进行中......

PS:GCC的等效工具是c++filt

答案 1 :(得分:0)

所以......它确实是原生库和CLR库之间的区别。当使用CLR库进行调用时,它会将$$ F插入到已损坏的名称中,但不会在从本机库中调用时进行调用。

有趣的是......我在一个创建对象的本地库中创建了一个类/函数......修复了它......加上我能够在CLR库代码中调用其他成员函数并且这样做了! / p>

答案 2 :(得分:0)

我遇到了同样的问题。我有一个带有非虚方法的抽象基类。 CLR 无法链接非虚方法,但是当我将函数更改为虚函数时,它起作用了!

所以 $$f 与虚拟方法有关,但名称 unmangler 并未如此显示。