Thanks.

"Curt Arnold" <[EMAIL PROTECTED]> wrote in message 
news:[EMAIL PROTECTED]
>
> On Feb 6, 2007, at 12:25 PM, Andrew Chalk wrote:
>
>> I had to upgrade an app. that used log4cxx. We made a lot of use of 
>> lines
>> like:
>>
>> LOG4CXX_INFO(eventLogger, _T("Binding to: " << sBindIP.c_str() <<  ". 
>> Port: "
>> << usPort << ". Link: " << sLinkNo.c_str()));
>>
>> I.e. we used inline ostringstream constructs.
>>
>> In 0.9.8 none of this appears to work. We appear to have to make major
>> modifications to our code along the lines of:
>>
>> ostringstream os;
>> os << _T("Binding to: " << sBindIP.c_str() << ". Port: " << usPort  << ".
>> Link: " << sLinkNo.c_str());
>> LOG4CXX_INFO(eventLogger, os.str().c_str());
>>
>> Am I missing a way to continue with inline ostringstream?
>>
>> Many thanks.,
>>
>
> The log4cxx 0.9.7 macros looked like:
>
> #define LOG4CXX_INFO(logger, message) { \
> if (logger->isInfoEnabled()) {\
> ::log4cxx::StringBuffer oss; \
> oss << message; \
> logger->forcedLog(::log4cxx::Level::INFO, oss.str(), __FILE__, 
>  __LINE__); }}
>
> And would allow you to pass a TCHAR* (where TCHAR was either char or 
> wchar_t depending on the compile flags) or any other statement  fragment 
> that could complete the oss << message statement.
>
> In log4cxx 0.10.0, we did not want the artificial limit of supporting 
> only one character type per build since many apps could easily use  both 
> char and wchar_t within the same application.  The macro looks  like:
>
> #define LOG4CXX_INFO(logger, message) { \
>         if (logger->isInfoEnabled()) {\
>             logger->forcedLog(::log4cxx::Level::INFO, message, 
> LOG4CXX_LOCATION); }}
>
> and the compiler picks the appropriate flavor of forcedLog  (std::string 
> or std::wstring) based on the type of the message  expression.  However 
> that requires that message be an expression and  not a statement fragment. 
> I do not believe that it is possible to  construct a macro that will both 
> accept statement fragments that  0.9.7 accepted and also support multiple 
> string types, but I'm  willing to be proved wrong.
>
> You appear to be misusing the Win32 _T construct (http:// 
> msdn2.microsoft.com/en-us/library/c426s321(VS.80).aspx) which is  intended 
> to be used to decorate a string literal so that it matches  the TCHAR 
> type.  For example, _T("Hello, World") would expand to  "Hello, World"L if 
> _UNICODE is set and "Hello, World" otherwise.  The  examples shown about 
> would not compile if _UNICODE was set since they  would just add a L to 
> the end of the fragment and change .c_str()  to .c_str()L.
>
> log4cxx no longer defines or uses _T.  It does define LOG4CXX_STR()  to 
> create string literals that match the internal logchar type,  however 
> LOG4CXX_STR should not be used in logging statements since  both char and 
> wchar_t flavors are provided regardless of the logchar  type.
>
> That is do
>
> LOG4CXX_INFO(logger, "Hello, World");
>
> or
>
> LOG4CXX_INFO(logger, "Hello, World"L);
>
> but do not do:
>
> LOG4CXX_INFO(logger, LOG4CXX_STR("Hello, World"));
>
> The last would compile and work properly, but it reflects a 
> misunderstanding of logchar as the internal char type.
>
> It appears from your fragments that you have no interest in wchar_t 
> strings (or other string types like CFString on Macs) and would be 
> willing to trade the multiple string type support for getting the 
> statement fragment support back.  You could create your own header  file 
> that you include after logger.h that redefines LOG4CXX_INFO et  al for 
> your own objectives, so instead of rewriting all your logging  calls, all 
> you have to do is create the header file and include it  where ever you 
> used statement fragments.
> 



Reply via email to