2
votes

Coming from C# I was recently moved to work on a Visual C++ 2010 project. Thing is I have been stuck with a problem with the use of CString for the most part of the day and no one around the office has found the solution.

Situation is: 2 projects with the same settings (unicode on, Use MFC in Shared DLL and NOT Using ATL among others).

In Project1 I have a function like this:

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

From Project2, I call the above function like this:

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

Compiling Project1 works just fine. When compiling Project2, I get an error:

Interface::ControlsWrappers::ETextBoxWrapper::GetValue' : none of the 5 overloads could convert all the argument types >c:\MFLDR\interface.dialogbase.dll: could be 'int

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

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

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

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

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

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

while trying to match the argument list >'(Microsoft::VisualC::MFC::CWinFormsControl, CString)' with [ TManagedControl=Interface::Controls::ETextBox ]

The bolded overload is the one it should be detecting as the CString, but it is asking for ATL::CStringT < wchar_t , StrTraitMFC_DLL < wchar_t , ATL::ChTraitsCRT > > instead of a CString.

As you can see at the end, the calling function correctly identifies the CString as a CString.

When going to the definition of CString, it redirects me to "afxstr.h" in both projects, finding:

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;

I modified the functions to look like:

In Project1:

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

In Project2, I call the above function like this:

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

And the compile error changed a bit. First part remains the same, but at the end:

while trying to match the argument list '(Microsoft::VisualC::MFC::CWinFormsControl, ATL::CStringT)' with [ TManagedControl=Lantek::Expert::Interface::Controls::ETextBox ] and [ BaseType=wchar_t, StringTraits=StrTraitMFC_DLL ]

If I twist it a little bit more and leave Project 1 like:

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

Then automatically and without compiling I get an error saying that BaseType and StringTraits are both undefined.

I don't know what's wrong. It would seem like one project is using one definition for CString and the other project a different definition, but both seems to be gettint the definition from the "afxstr.h". I've read a lot on the Internet but no one seems to be having a problem like this, or at least I haven't found a related issue.

I'm in the dark here, so any help would be appreciated. Thanks in advance.

3
Looking at the code, snippets you have shown: You are not using C++, but rather are using C++/CLI. - Algirdas Preidžius
Try to include cstringt.h header which contains the definition for MFC CString class - Sergey Shevchenko
@SergeyShevchenko Done that in corresponding .cpp files in both Project1 and Project2, but unfortunately I keep getting the same error. Thanks anyway! - KostasKoufos
Ok. For me it's hard to guess what's wrong. It would be nice if you can create a sample project with a minimum amount of code that reproduce the issue and upload it somewhere. - Sergey Shevchenko

3 Answers

0
votes

It is looks like there is abbiguity between MFC's CString and ATL's CString.

To verify this is the problem, try to use ATL::CStringT< TCHAR, StrTraitMFC_DLL< TCHAR > > instead of CString.

0
votes

Thanks for the feedback received so far. After more investigation we have narrowed down the problem:

  • Somehow Project1 is using the ATL definition (atlstr.h) of CString and Project2 is using the MFC definition.(afxstr.h)

Having said that, I am still unable to make this work.I don't understand how they are taking different definitions as project settings are - apparently - the same (unicode, atl support, crt, etc).

There is some info on the internet with problems relating to CString definitions of MFC vs ATL, but most of them are pretty old, before mfc-atl library was joined and the problem is usually a LNK2019. In my V2015 i get error code C2665.

0
votes

Finally I couldn't solve this so I had to work out a workaround. I encapsulated a CString inside a class that I made public to the other project. My getValue method now requieres CStringPublic, but calling this getValue method with a simple CString works, so I don't have to change anything in Project 2.

My wrapper class:

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 Method:

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

You can call GetValue like:

CString test;
GetValue(textBox, test);

And you would get the value in test variable.