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. >
