使用Clang / VS-2019构建的MFC / DLL中缺少ATL :: CStringT函数

时间:2019-08-01 11:59:47

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

最近在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。

关于, 阿德里安

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

啊哈!我有一个修复程序(暂时),但是依赖于以下事实:我正在构建的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内容。