log4cxx warning 관련 C4275

C++ 2012. 4. 6. 22:55



이전에 log4cxx 빌드 글(http://yamoe.tistory.com/173) 에서 계속되는 글입니다.


log4cxx 를 dll 빌드 후 사용하려고 하면 C4275 경고가 발생합니다.


1>c:\program files\microsoft visual studio 10.0\vc\include\vector(481): warning C4275: DLL 인터페이스가 아닌 struct 'std::_Container_base12'이(가) DLL 인터페이스 class 'std::_Vector_val<_Ty,_Alloc>'의 기본으로 사용되었습니다.

1>          with

1>          [

1>              _Ty=log4cxx::AppenderPtr,

1>              _Alloc=std::allocator<log4cxx::AppenderPtr>

1>          ]

1>          c:\program files\microsoft visual studio 10.0\vc\include\xutility(73) : 'std::_Container_base12' 선언을 참조하십시오.

1>          d:\src\newbaseapp\library\log4cxx\include\log4cxx\appender.h(141) : 컴파일 중인 클래스 템플릿 인스턴스화 'std::vector<_Ty>'에 대한 참조를 확인하십시오.

1>          with

1>          [

1>              _Ty=log4cxx::AppenderPtr

1>          ]

1>c:\program files\microsoft visual studio 10.0\vc\include\vector(481): warning C4275: DLL 인터페이스가 아닌 struct 'std::_Container_base12'이(가) DLL 인터페이스 class 'std::_Vector_val<_Ty,_Alloc>'의 기본으로 사용되었습니다.

1>          with

1>          [

1>              _Ty=log4cxx::LoggerPtr,

1>              _Alloc=std::allocator<log4cxx::LoggerPtr>

1>          ]

1>          c:\program files\microsoft visual studio 10.0\vc\include\xutility(73) : 'std::_Container_base12' 선언을 참조하십시오.

1>          d:\src\newbaseapp\library\log4cxx\include\log4cxx\logger.h(52) : 컴파일 중인 클래스 템플릿 인스턴스화 'std::vector<_Ty>'에 대한 참조를 확인하십시오.

1>          with

1>          [

1>              _Ty=log4cxx::LoggerPtr

1>          ]

1>c:\program files\microsoft visual studio 10.0\vc\include\vector(481): warning C4275: DLL 인터페이스가 아닌 struct 'std::_Container_base12'이(가) DLL 인터페이스 class 'std::_Vector_val<_Ty,_Alloc>'의 기본으로 사용되었습니다.

1>          with

1>          [

1>              _Ty=log4cxx::spi::HierarchyEventListenerPtr,

1>              _Alloc=std::allocator<log4cxx::spi::HierarchyEventListenerPtr>

1>          ]

1>          c:\program files\microsoft visual studio 10.0\vc\include\xutility(73) : 'std::_Container_base12' 선언을 참조하십시오.

1>          d:\src\newbaseapp\library\log4cxx\include\log4cxx\spi\hierarchyeventlistener.h(56) : 컴파일 중인 클래스 템플릿 인스턴스화 'std::vector<_Ty>'에 대한 참조를 확인하십시오.

1>          with

1>          [

1>              _Ty=log4cxx::spi::HierarchyEventListenerPtr

1>          ]

1>c:\program files\microsoft visual studio 10.0\vc\include\vector(481): warning C4275: DLL 인터페이스가 아닌 struct 'std::_Container_base12'이(가) DLL 인터페이스 class 'std::_Vector_val<_Ty,_Alloc>'의 기본으로 사용되었습니다.

1>          with

1>          [

1>              _Ty=log4cxx::LogString,

1>              _Alloc=std::allocator<log4cxx::LogString>

1>          ]

1>          c:\program files\microsoft visual studio 10.0\vc\include\xutility(73) : 'std::_Container_base12' 선언을 참조하십시오.

1>          d:\src\newbaseapp\library\log4cxx\include\log4cxx\spi\loggingevent.h(46) : 컴파일 중인 클래스 템플릿 인스턴스화 'std::vector<_Ty>'에 대한 참조를 확인하십시오.

1>          with

1>          [

1>              _Ty=log4cxx::LogString

1>          ]

1>c:\program files\microsoft visual studio 10.0\vc\include\vector(481): warning C4275: DLL 인터페이스가 아닌 struct 'std::_Container_base12'이(가) DLL 인터페이스 class 'std::_Vector_val<_Ty,_Alloc>'의 기본으로 사용되었습니다.

1>          with

1>          [

1>              _Ty=log4cxx::spi::LoggingEventPtr,

1>              _Alloc=std::allocator<log4cxx::spi::LoggingEventPtr>

1>          ]

1>          c:\program files\microsoft visual studio 10.0\vc\include\xutility(73) : 'std::_Container_base12' 선언을 참조하십시오.

1>          d:\src\newbaseapp\library\log4cxx\include\log4cxx\spi\loggingevent.h(253) : 컴파일 중인 클래스 템플릿 인스턴스화 'std::vector<_Ty>'에 대한 참조를 확인하십시오.

1>          with

1>          [

1>              _Ty=log4cxx::spi::LoggingEventPtr

1>          ]

1>Manifest:



대충 저렇게 나오는데...

이유는 log4cxx dll이 사용하는 CRT와 갖다 쓰는 프로그램의 CRT 라이브러리가 달라서 STL 에서 에러가 발생합니다.

무시하고 쓰라는 글도 있는데 이거 LogString 같은 log4cxx dll 메모리 영역에서 생성된 인스턴스가 사용하는 프로그램에서 자원 해제되는 경우가 생기면 힙손상으로 프로그램이 다운 로드 됩니다. (이전글에서 log4cxx.dll을 /MT, /MTd 로 빌드 했습니다.)

이건 dll 작성시 stl 관련 객체가 export 될때 문제 및 각각 별도의 메모리 영역에서 한쪽에서 new 된게 다른쪽에서 delete 될때의 문제 입니다.


STL을_DLL에서_Export_할때_문제점.pdf



LogString 같은 log4cxx.dll 에서 생성되는 객체를 사용하지 않는다면 안죽고 쓸 수 있겠지만.. 상당히 찝찝합니다.

해결책은 2가지가 있는데

해결책1. log4cxx.dll 을 /MD, /MDd 로 빌드 하고 가져다 쓰는 프로그램도 /MD, /MDd 로 빌드하여 쓴다.

전 가져다 쓰는 프로그램에서 /MT, /MTd 로 빌드하고 싶어서 이 방법은 포기.

하지만 이게 정석입니다.

해결책2. log4cxx 를 static 라이브러리로 빌드하여 정적 링크하여 사용한다.

이걸 사용했습니다. 사용한 옵션들은 아래 log4cxx static 빌드 를 참조


log4cxx static 빌드

빌드시 : 

구성형식 : 정적 라이브러리(.lib)

코드생성 > 런타임 라이브러리 : /MT, /MTd

전처리기 : LOG4CXX_STATIC 추가


사용시 : 

코드생성 > 런타임 라이브러리 : /MT, /MTd

전처리기 : LOG4CXX_STATIC 추가

라이브러리 사용 추가 : 

log4cxx 라이브러리 : log4cxx.lib, apr.lib, aprutil.lib, xml.lib

log4cxx에서 사용하는 라이브러리 : mswsock.lib, ws2_32.lib


디버깅 정보 포함을 위해 :  (.pdb 없다고 경고 보기 싫어서)

1) C/C++ > 일반 > 디버깅 정보 형식 > C7 호환(/Z7)

2) C/C++ > 코드 생성 -> 최소 다시 빌드 가능 > 아니오

3) C/C++ >명령줄 > /Ylsymbol 입력

이상입니다.




추가로 log4cxx 에서 appender 별로 xml 로깅 설정을 사용하는 좋은 샘플이 있습니다.

http://www.dreamcubes.com/b2/software-development/10/log4cxx-tutorial-in-visual-c/