Thanks for the tip, Curt! Mike
-----Original Message----- From: Curt Arnold [mailto:[EMAIL PROTECTED] Sent: Wednesday, April 23, 2008 9:30 PM To: Log4CXX User Subject: Re: Problem logging unicode MFC/ATL CString with LOG4CXX_* macros On Apr 23, 2008, at 8:12 PM, Jara, Mike SEA wrote: > I'm having trouble getting (Windows) MFC or ATL CStrings to log > properly, when using the LOG4CXX_* macros. For example, this will log > the pointer's hex value, rather than the string contents: > > CString sMyString(_T("Test CString")); > LOG4CXX_DEBUG(MyLogger, sMyString); > > CString does implement a cast operator to LPCTSTR (wchar_t* in my > case). > If I explicitly call this, the string logs properly: > > CString sMyString(_T("Test CString")); > LOG4CXX_DEBUG(MyLogger, (LPCTSTR)sMyString); > > I would expect this cast operator to be implicitly called inside > MessageBuffer, to make the argument comply with the function > signature. > I think this is the function that should be called: > > WideMessageBuffer& MessageBuffer::operator<<(const wchar_t* msg); > > But when I step through in the debugger, I see that there is a global > cast operator called instead. I assume it's a better fit, as far as > the > compiler's concerned: > > template<class V> > std::ostream& operator<<(MessageBuffer& os, const V& val) { > return ((std::ostream&) os) << val; > > I tried commenting this cast operator out, and then I no longer have > to > cast my CString! But I'm afraid this was probably put in for a > reason, > and I hate to just hack something when I don't completely understand > it. > Does anyone know if I can safetly remove this? Looking at the change > list, I see it was added by "carnold" on 11/6/07, revision number > 592542. > > I'm using the last snapshot before the 0.10 release, by the way. > > Any help would be appreciated. > > Thanks! > Mike The template that you mentioned basically says that when attempting to insert, you do not recognize the right hand side as a recognized string type (char*, wchar_t*, std::string, std::wstring), then use any available insertion operator for a std::ostream and force the rest of the expression to be char* based. What you'd like to have is something like the following in scope: #if defined(_UNICODE) WideMessageBuffer& operator<<(MessageBuffer& buf, const CString& str) { return buf << (const wchar_t*) str; } WideMessageBuffer& operator<<(WideMessageBuffer& buf, const CString& str) { return buf << (const wchar_t*) str; } #else CharMessageBuffer& operator<<(MessageBuffer& buf, const CString& str) { return buf << (const char*) str; } CharMessageBuffer& operator<<(CharMessageBuffer& buf, const CString& str) { return buf << (const char*) str; } #endif which should take precedence over the fallback insertion operation.