【问题标题】:Missing ATL::CStringT function in MFC/DLL Builds with Clang/VS-2019使用 Clang/VS-2019 构建的 MFC/DLL 中缺少 ATL::CStringT 函数
【发布时间】:2019-12-10 00:34:19
【问题描述】:

最近在 Visual Studio 2019 中安装了新的 LLVM/clang-cl 工具集,这是一个潜在的出色补充!但是,在构建我的 EXE 和 DLL 文件时,我在链接时收到以下错误:

lld-link : error : undefined symbol: "__declspec(dllimport) public: static void __cdecl ATL::CSimpleStringT<wchar_t, 1>::CopyChars(wchar_t *, unsigned __int64, wchar_t const *, int)" (__imp_?CopyChars@?$CSimpleStringT@_W$00@ATL@@SAXPEA_W_KPEB_WH@Z)

只有在使用“在共享 DLL 中使用 MFC”和在“发布”配置中进行构建时才会发生这种情况:即,使用“在静态库中使用 MFC”或在“调试”配置中,错误就会消失。

'违规函数在 cstringt.h 标头中使用 _ATL_INSECURE_DEPRECATE("blah blah") 属性定义,但将其重新定义为 'empty' 并不能解决问题。

要重现,请使用新建项目向导在 VS-2019 中创建一个默认的 MFC、基于对话框的应用程序,并在 OnInitDialog() 函数中添加以下内容:

// TODO: Add extra initialization here
    CString txt1 = L"Hello, ";
    CString txt2 = L"world!";
    CString mess = txt1 + txt2;
    SetDlgItemText(IDC_STATIC, mess);

默认构建以检查,然后将“平台工具集”切换到“LLVM (clang-cl)”并重新构建!您需要在生成的“framework.h”文件末尾注释掉或禁用与清单相关的行:

    #ifndef __clang__
    #ifdef _UNICODE
    #if defined _M_IX86
    #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
    #elif defined _M_X64
    #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
    #else
    #pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
    #endif
    #endif
    #endif

我在全局标题中尝试了以下#defines,但无济于事:

    #define _CRT_SECURE_NO_DEPRECATE
    #define _SECURE_ATL 0
    #define _SECURE_SCL 0
    #define _ATL_INSECURE_DEPRECATE(a)
    #define _ATL_DEBUG_INTERFACES

所以:(1) 这是我应该向 Microsoft 报告的“错误”还是我在做一些愚蠢的事情? (2) 任何人都可以建议一个补丁/修复,这样我就可以用 clang 真正测试我的 MFC 项目吗?注意:我必须在 DLL 中使用 MFC,因为我依赖扩展 DLL。

【问题讨论】:

    标签: c++ mfc visual-studio-2019 clang-cl


    【解决方案1】:

    啊哈!我有一个可行的修复程序(目前),但依赖于我正在构建的 EXE 都调用一个我也构建的公共 DLL 的事实。我将此代码添加到该 DLL 的源代码中,它们现在构建并运行!

    template<> void __declspec(dllexport) __cdecl ATL::CSimpleStringT<wchar_t,1>::CopyChars(wchar_t *pchDest, size_t, const
        wchar_t *pchSrc, int nChars) throw()
    {
        memcpy(pchDest, pchSrc, size_t(nChars) * sizeof(wchar_t));
        return;
    }
    

    但是,这取决于我调用该 DLL 的事实。对于其他没有的应用程序,我(还)不能让这种方法发挥作用。此外,我的“MFC 扩展 DLL”似乎不喜欢它:它们是可选的“插件”模块,但当我尝试加载一个模块时只会导致完全退出/崩溃——但这可能是由其他一些因素,因为这使用了非常深刻/微妙的 MFC 东西。

    【讨论】:

      【解决方案2】:

      我遇到了同样的问题,发现在项目配置中禁用内联函数扩展(/Ob0)可以解决问题。您是否碰巧启用了它(/Ob1 或 /Ob2)?

      【讨论】:

      • 是的,这行得通!但是,我担心的是对优化的影响。
      • 我已将问题报告给 VS 支持团队,现在它被标记为“正在调查中”。我会将这个修复传递给他们,因为它可以帮助他们解决问题。
      • 是的,优化会受到影响,但这对我来说并不是什么大问题。我使用 LLVM 工具集作为补充,以启用基于 clang 的工具验证我的项目。对于生产,我仍然使用 MSVC 之一。从 VS 支持部门获得更多信息后,请发布更新。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-11-12
      • 2013-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多