Uploaded image for project: 'Log4cxx'
  1. Log4cxx
  2. LOGCXX-274

Logging MFC CString's produce unexpected results in Unicode builds

    XMLWordPrintableJSON

Details

    • Improvement
    • Status: Resolved
    • Major
    • Resolution: Cannot Reproduce
    • 0.10.0
    • None
    • None
    • None

    Description

      Mike Jara reported an unexpected behavior on log4cxx-user on 2008-04-24 (http://marc.info/?t=120899966300001&r=1&w=2)

      --------

      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 problem is that CString is not recognized as a wide-string type and a fallback insertion operator template basically applies operator<<(std::ostream&, CString&). The template made an arbitrary choice that if no other insertion operator was available, then hope that there was an insertion operator for a char* based stream since it would be more likely to be present and functional than std::wostream insertion operator.

      Based on the comment, Inserting a Unicode CString into a std::ostream does not transcode the CString into the current code page, but outputs the pointer's hex value (at least for the version of MFC that Mike tried).

      A temporary resolution is to define add something like:

      #if defined(_UNICODE)
      WideMessageBuffer& operator<<(MessageBuffer& buf, const CString& str) {
      return buf << (const wchar_t*) str;
      }
      #else
      CharMessageBuffer& operator<<(MessageBuffer& buf, const CString& str) {
      return buf << (const char*) str;
      }
      #endif

      However, it would be nice (but maybe not practical) to provide this in the standard headers.

      The issues are:

      1. log4cxx should not have an MFC dependency, so the insertion operator needs to be implemented on the callers side.
      2. log4cxx headers should not include MFC headers exception when explicit that the app is being compiled with MFC.

      Will have to explore to come up with a good solution, Possibilities:

      Adding operator definition to log4cxx.hw
      Adding operator definition to logger.h
      Adding macro to control character type used by templated insertion operator
      Add mfclogger.h and possibly mfcloggerimpl.h

      Attachments

        Issue Links

          Activity

            People

              carnold@apache.org Curt Arnold
              carnold@apache.org Curt Arnold
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: