2013-07-18 1 views
0

#define 지시문과 매크로를 사용하여 코드에서 log4cxx를 사용하여 캡슐화하려고했습니다. 코드가 컴파일되지만 실행시 스트림 개체가 올바르게 초기화되지 않았으므로 액세스 위반이 발생합니다.<< 연산자와 매크로를 사용하여 log4cxx 액세스 예외

이 같은 log4cxx 플러그 모양 만들기 위해 시도 헤더 파일 :

#ifdef USE_LOG4CXX 
#include "log4cxx/logger.h" 

#define LOG_DEBUG(msg) LOG4CXX_DEBUG(logger, msg) 
#define LOG_INFO(msg) LOG4CXX_INFO(logger, msg) 
#define LOG_WARN(msg) LOG4CXX_WARN(logger, msg) 
#define LOG_ERROR(msg) LOG4CXX_ERROR(logger, msg) 

#define LOGGER_DECL static const log4cxx::LoggerPtr logger 
#define LOGGER_INIT(source,name) const log4cxx::LoggerPtr source::logger = log4cxx::Logger::getLogger(#name); 
#else // use some other log method, e.g. stdout which worked fine 

.cpp 파일 로깅과 같이 수행합니다

LOG_INFO("state(): " << old_state << " ==> " << new_state); 

전처리가 .cpp 파일을 확장을 :

{ if (logger->isInfoEnabled()) { ::log4cxx::helpers::MessageBuffer oss_; logger->forcedLog(::log4cxx::Level::getInfo(), oss_.str(oss_ << "state(): " << state_ << " ==> " << new_state), ::log4cxx::spi::LocationInfo("c:\\dev\\ezx-capi\\iserver-api\\iserver_client.cpp", __FUNCSIG__ , 190)); }}; 

old_state 및 new_state의 데이터 유형은입니다.. 그것은, 디버거에서

std::basic_ostream<char>& operator<<(CharMessageBuffer& os, const V& val) { 
    return ((std::basic_ostream<char>&) os) << val; 
} 

CharMessageBuffer 개체가 초기화되지 않은 std::basic_streambuf 멤버가 같은 문제가보고,이 값을 추가 간다 그래서 때

실행

, 응용 프로그램에 실패 죽는다. (그래도 난 그 설명에 대해 확실하지 않다.) 모든 방법 드릴 다운

, 그것은 std::basic_ostream에서 사망 :

_Myt& __CLR_OR_THIS_CALL operator<<(int _Val) 
    { // insert an int 
    ios_base::iostate _State = ios_base::goodbit; 
    const sentry _Ok(*this); // dies right here, in the constructor 

을 어쨌든, 나는 이것이 어떻게 매크로를 사용하고 함께 할 수있는 뭔가가 실현 LOG4CXX를 호출합니다. (필자는 USE_LOG4FXX가 정의되지 있었을 때, 모든 로그 문은 std::cout 가고 있었다 그것은 괜찮 았는데.)

UPDATE

정보

또 다른 조각 - 내가 호출 할 때이는 실패한 것 같다 정적 라이브러리 내에서 로깅. EXE 프로젝트에서 같은 (또는 비슷한) 매크로를 사용하면 전혀 실패하지 않습니다. 그래서 어떤 종류의 별도의 테스트 응용 프로그램에서이 문제를 재현 할 수 없습니다.

답변

0

이 문제는 열거 형을 해석 한 방식으로 인해 발생했습니다. 컴파일러는 << 연산자 대신 int 유형을 취한 << 연산자 템플릿을 호출했습니다. 무엇 (나에게), 심지어 낯선 사람이고, 내가 쓴 테스트 앱이 열거 형 데이터 형식이 문제가 즉, 문제없이 작동 여부를 확인이었다 :

ezx::net::client_state::state mystate = ezx::net::client_state::connecting; 
LOG_INFO("this should show new state" << mystate); 

이 어떤 오류가 발생하지 않았고, 다른했다 코드 경로는 위의 동일한 코드보다 큽니다.

결론적으로이 연산자의 log4cxx 구현은 깨지기 쉽지만 컴파일시 올바르게 작동하지만 데이터 유형이 올바른 버전의 연산자로 전달되는지 여부에 따라 런타임에 예기치 않게 실패합니다.

관련 문제