【问题标题】:Error calling function with CString parameter by reference通过引用使用 CString 参数调用函数时出错
【发布时间】:2019-01-16 14:46:41
【问题描述】:

来自 C# 我最近被调去从事一个 Visual C++ 2010 项目。问题是我在一天中的大部分时间都被 CString 的使用所困扰,办公室周围没有人找到解决方案。

情况是:2 个项目具有相同的设置(unicode 开启、在共享 DLL 中使用 MFC 和不使用 ATL 等)。

在 Project1 中我有这样的功能:

BOOL ETextBoxWrapper::GetValue (ETextBox ^textBox ,CString &value)

从 Project2 中,我这样调用上面的函数:

ETextBoxWrapper::GetValue (m_txtText, m_cText) ;//m_TxtText is a ETextBox and m_cText is a CString

编译 Project1 工作正常。编译Project2时出现错误:

Interface::ControlsWrappers::ETextBoxWrapper::GetValue' : 没有 5 个 重载可以转换所有参数类型 >c:\MFLDR\interface.dialogbase.dll: 可以是 'int

Interface::ControlsWrappers::ETextBoxWrapper::GetValue(Interface::Controls::ETextBox ^,long &)

Interface::ControlsWrappers::ETextBoxWrapper::GetValue(Interface::Controls::ETextBox ^,long &)'

c:\MFLDR\einterface.dialogbase.dll: 或 'int >Interface::ControlsWrappers::ETextBoxWrapper::GetValue(Interface::Controls::ETextBox ^,int &)'

c:\MFLDR\interface.dialogbase.dll: 或'int Interface::ControlsWrappers::ETextBoxWrapper::GetValue(Interface::Controls::ETextBox ^,double &)'

c:\MFLDR\interface.dialogbase.dll: 或 'int Interface::ControlsWrappers::ETextBoxWrapper::GetValue(Interface::Controls::ETextBox ^, ATL::CStringT > &)'

c:\MFLDR\interface.dialogbase.dll: 或'int Interface::ControlsWrappers::ETextBoxWrapper::GetValue(Interface::Controls::ETextBox ^,wchar_t *)'

在尝试匹配参数列表时 >'(Microsoft::VisualC::MFC::CWinFormsControl, CString)' 与 [ TManagedControl=Interface::Controls::ETextBox ]

粗体重载是它应该检测为 CString 的重载,但它要求 ATL::CStringT > 而不是 CString.

正如你在最后看到的,调用函数正确地将 CString 识别为 CString。

当转到 CString 的定义时,它会将我重定向到两个项目中的“afxstr.h”,发现:

typedef ATL::CStringT< wchar_t, StrTraitMFC_DLL< wchar_t > > CStringW;
typedef ATL::CStringT< char, StrTraitMFC_DLL< char > > CStringA;
typedef ATL::CStringT< TCHAR, StrTraitMFC_DLL< TCHAR > > CString;

我将函数修改为如下所示:

在项目 1 中:

BOOL ETextBoxWrapper::GetValue (ETextBox ^textBox ,ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > >&value)

在 Project2 中,我这样调用上述函数:

ATL::CStringT<wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > > auxiliar (m_cText) ;
ETextBoxWrapper::GetValue (m_txtText, auxiliar) ;

并且编译错误发生了一些变化。第一部分保持不变,但在最后:

在尝试匹配参数列表“(Microsoft::VisualC::MFC::CWinFormsControl, ATL::CStringT)”时 与 [ TManagedControl=Lantek::Expert::Interface::Controls::ETextBox ] 和 [ BaseType=wchar_t, StringTraits=StrTraitMFC_DLL ]

如果我稍微扭曲一下,然后像这样离开项目 1:

BOOL ETextBoxWrapper::GetValue (ETextBox ^textBox ,ATL::CStringT<BaseType,StringTraits> &value)

然后自动且不编译我得到一个错误,说 BaseType 和 StringTraits 都是未定义的。

我不知道怎么了。似乎一个项目对 CString 使用一个定义,而另一个项目使用不同的定义,但两者似乎都是从“afxstr.h”中获取定义。我在互联网上阅读了很多,但似乎没有人遇到这样的问题,或者至少我没有找到相关的问题。

我在这里一无所知,因此我们将不胜感激。提前致谢。

【问题讨论】:

  • 查看代码,sn-ps 显示:您不是使用 C++,而是使用 C++/CLI。
  • 尝试包含 cstringt.h 标头,其中包含 MFC CString 类的定义
  • @SergeyShevchenko 在 Project1 和 Project2 的相应 .cpp 文件中完成了该操作,但不幸的是我一直收到相同的错误。还是谢谢!
  • 好的。对我来说,很难猜出哪里出了问题。如果您可以使用最少的代码创建一个示例项目来重现问题并将其上传到某处,那就太好了。

标签: mfc c++-cli


【解决方案1】:

看起来 MFC 的 CString 和 ATL 的 CString 之间存在歧义。

要验证这是问题所在,请尝试使用ATL::CStringT&lt; TCHAR, StrTraitMFC_DLL&lt; TCHAR &gt; &gt; 而不是CString

【讨论】:

  • 是的,模棱两可是我的想法,但作为语言和框架的新手,我不知道该去哪里找。我尝试在 GetValue 中使用您的定义,但遇到了与情况 2 中相同的错误。无论如何,谢谢!
【解决方案2】:

感谢您迄今为止收到的反馈。经过更多调查,我们缩小了问题范围:

  • 不知何故,Project1 正在使用 CString 的 ATL 定义 (atlstr.h),而 Project2 正在使用 MFC 定义。(afxstr.h)

话虽如此,我仍然无法完成这项工作。我不明白他们如何采用不同的定义,因为项目设置 - 显然 - 相同(unicode、atl 支持、crt 等)。

互联网上有一些关于 MFC 与 ATL 的 CString 定义相关的问题的信息,但其中大多数都相当旧,在加入 mfc-atl 库之前,问题通常是 LNK2019。在我的 V2015 中,我收到错误代码 C2665。

【讨论】:

    【解决方案3】:

    最后我无法解决这个问题,所以我不得不想出一个解决方法。我将一个 CString 封装在一个对其他项目公开的类中。我的 getValue 方法现在需要 CStringPublic,但是用一个简单的 CString 调用这个 getValue 方法是可行的,所以我不必在 Project 2 中进行任何更改。

    我的包装类:

    class CStringPublic {
        public:
        CStringPublic ( CString &string ) { m_string = &string ; }
        CStringPublic& operator=(const CString &string) { *m_string = string ; return *this ; }
        operator CString () { return *m_string ; }
    
    private:
        CString *m_string ;
    } ;
    

    GetValue 方法:

    BOOL ETextBoxWrapper::GetValue (ETextBox ^textBox ,CStringPublic value)
    

    您可以像这样调用 GetValue:

    CString test;
    GetValue(textBox, test);
    

    你会得到测试变量中的值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-12
      • 2019-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多