解密损坏的 C++ 名称 $$F
Deciphering Mangled C++ names $$F
我的非托管 C++ 中有以下函数调用 class:
_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
完整 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 Studio17\Enterprise\VC\Tools\MSVC.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\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 :精确 / Zc : wchar_t / Zc : forScope / Zc : 内联 / 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.cppCTPSpi.cpp
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
所以...它确实是本机库和 CLR 库之间的区别。当调用是从 CLR 库中进行时,它会将 $$F 插入到损坏的名称中,但当调用是从本机库中进行时则不会。
有趣的是...我在创建对象的本机库中创建了一个 class / 函数...修复了它...而且我能够从 CLR 库中调用其他成员函数代码并且有效!
我遇到了同样的问题。我有一个带有非虚拟方法的抽象基础 class。 CLR 无法 link 反对非虚拟方法,但是当我将函数更改为虚拟方法时它起作用了!
所以 $$f
与方法是虚拟的有关,但是名称 unmangler
没有显示它。
我的非托管 C++ 中有以下函数调用 class:
_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
完整 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 Studio17\Enterprise\VC\Tools\MSVC.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\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 :精确 / Zc : wchar_t / Zc : forScope / Zc : 内联 / 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.cppCTPSpi.cpp
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
所以...它确实是本机库和 CLR 库之间的区别。当调用是从 CLR 库中进行时,它会将 $$F 插入到损坏的名称中,但当调用是从本机库中进行时则不会。
有趣的是...我在创建对象的本机库中创建了一个 class / 函数...修复了它...而且我能够从 CLR 库中调用其他成员函数代码并且有效!
我遇到了同样的问题。我有一个带有非虚拟方法的抽象基础 class。 CLR 无法 link 反对非虚拟方法,但是当我将函数更改为虚拟方法时它起作用了!
所以 $$f
与方法是虚拟的有关,但是名称 unmangler
没有显示它。