Thanks.
"Curt Arnold" <carnold@xxxxxxxxxx> wrote in message
news:9823CEE2-D8F9-4D3D-87F3-11944237E318@xxxxxxxxxxxxx
>
> 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.
>
|