WindowsSDK Visual Studio, Visual Studio Servicepack의 일부 include되는 파일셋은 서로 설치하면서 덮어 써집니다.

 

따라서, 가장 최신에 나온 파일이 가장 나중에 덮어 써지게 설치를 해야 합니다. Visual Studio2008을 예로 들면, 설치 순서는

 

Visual Studio2008 -> Visual Studio SDK 6.1 -> Visual Studio Service pack1 -> Security Update

 

순으로 이루어 져야 합니다.

 

 

특히 예전 Embedded C++로 개발할 때 온갖 툴과 SDK셋들을 설치 했을 때는 Embedded C++툴을 Visual Studio와 함께 설치 오더를 맞추어 줘야 했습니다. 설치 오더가 틀리면, 컴파일이 안되던가, 링크가 안되던가 등등 개발자를 당황스럽게 하는 문제를 발생시킵니다.

 

 

이번에 Visual Studio 2008 Servicepack1용 보안 업데이트인 MS09-035(http://support.microsoft.com/kb/971092)를 설치했을 때 설치 오더가 맞지 않을 경우 컴파일이 안 되는 문제가 있었습니다.

 

 

만일, Visual Studio Servicepack1를 설치한 후 SDK를 설치했을 때, Servicepack1의 최신 CRT파일을 SDK6.1의 구 CRT파일로 교체 된 다음 VisualStudio2008 Servicepack1 ATL보안 업데이트를 하고 나면, vector를 사용한 소스 컴파일 시 아래와 같은 에러가 뜨게 됩니다.

 

error C2039: '_Swap_adl' : is not a member of 'std'    c:\program files\microsoft visual studio 9.0\vc\include\xutility    2764

error C3861: '_Swap_adl': identifier not found    c:\program files\microsoft visual studio 9.0\vc\include\xutility    2764

 

 

문제의 원인은 Visual Studio 2008 설치 후 Servicepack1을 설치해서 최신 CRT셋으로 교체 했지만, 그 후 SDK6.1에 있는 오리지날 Visual Studio2008 파일 셋으로 일부 CRT관련 파일이 롤백 되었고 Servicepack1용 보안 업데이트에서 교체한 CRT파일이 Servicepack1 CRT셋에서 추가된 파일을 사용하기 때문입니다.

 

 

문제 해결 방법은,

 

 

에러 메시지가 나타내주듯, C:\Program Files\Microsoft Visual Studio 9.0\VC\include\xutility 2764라인에서 사용된 _Swap_adl의 정의를 아래와 같이 _Swap_adl사용 시점 윗부분에 추가해 주던가,

 

// TEMPLATE FUNCTION _Swap_adl

template<class _Ty> inline

void _Swap_adl(_Ty& _Left, _Ty& _Right)

{    // exchange values stored at _Left and _Right, using ADL

swap(_Left, _Right);

}

 

 

에러가 난 시점에서 Servicepack1과 보안업데이트를 순서대로 다시 설치해 주시면 됩니다.

 

 

SDK Servicepack을 설치할 때 설치 오더가 있다는 점을 분명히 알아 두시고, 설치시 Requirement부분을 참고 하시면 도움이 됩니다.

 

마찬가지 이유로, Servicepack, 보안 업데이트로 인해 최신 파일셋이 설치된 다음, SDK 인스톨파일로 SDK 복구를 하게 되면 다시 SDK파일 셋으로 롤백되니 파일셋을 복구 하실 때는 설치 오더를 고려해서 복구를 하셔야 합니다.

출처 : devpia.co.kr(데브피아 VC++ 마을)

Posted by 배고파씨
Visual C++ 2008 Express Edition에서도 WTL을 사용하는 방법.

1. Visual C++ 2008 Express Edition을 설치하게 되면 기본적으로 'Microsoft Windows SDK for Visual Studio 2008 Headers and Libraries'가 설치가 됩니다. 하지만, 이 SDK에는 ATL 및 MFC와 관련된 헤더 파일이 없습니다. (WTL을 사용하려면 ATL 헤더가 필요)

2. 따라서 이전 버전인 Windows Server® 2003 R2 Platform SDK을 다운로드 받으셔서 설치하신 후, 이 SDK가 설치된 폴더(보통 C:\Program Files\Microsoft Platform SDK)에 가셔서 include 폴더 아래에 있는 atl 폴더에 있는 파일 모두를 WTL의 include 폴더로 복사하시면 됩니다.

* 이 과정이 귀찮으신 분들을 위해 따로 파일을 모아서 올려두었습니다.


ATL header files for WTL


3. 아래에 첨부한 'WTL Application Wizard for VC 9.0'를 WTL이 설치된 폴더의 AppWiz 폴더에 압축을 풀어서 setup90x.js을 실행합니다.


WTL Application Wizard for VC 9.0

 
4. VC++을 실행하여 Tools - Options 메뉴를 선택하여 Projects and Solutions - VC++ Directories 항목을 선택하여 Show directories for 항목의 include files를 선택하여 WTL이 있는 폴더를 등록합니다. 그리고 File - New - Project 메뉴를 선택하여 WTL 프로젝트를 선택하여 프로젝트를 생성합니다.

5. 만약 컴파일 중에 'ATL.LIB'가 없다는 메시지가 나오면 Project - Properties에 가셔서 Configuration Properties - General의 'Use of ATL'을 'Static Link to ATL'로 변경하시면 됩니다.
Posted by 배고파씨
문제

WTL Project를 생성후 ATL Simple Object class를 Add Class Wizard로 추가할때 "ATL classes can only be added MFC EXE and MFC DLL projects or projects with full ATL support"라는 에러가 뜬다.

원인

해당 Wizard에서 WTL Project가 ATL을 지원한다는 것을 이해하지 못해서이다.

해결

VisualStudio Wizard관련 파일을 일부 수정한다.

http://www.codeproject.com/wtl/WTLExpress.asp?df=100&forumid=255873&exp=0&select=1637863#xx1637863xx

One solution is to modify C:\Program Files\Microsoft Visual Studio 8\VC\VCWizards\1033\common.js as follows:

1. locate the function
IsATLProject

2. change the line:
if (strTypeString == "ATL::CComModule" || strTypeString == "ATL::CAutoThreadModule")
to:
if (strTypeString == "ATL::CComModule" || strTypeString == "ATL::CAutoThreadModule" || strTypeString == "WTL::CServerAppModule" || strTypeString == "WTL::CAppModule")

3. save your changes
Posted by 배고파씨
WTL에도 WTL::CString 클래스가 존재한다.
이건 이전 MFC의 CString 클래스와 유사하게 만든 것이다.
그런데 이젠 ATL에도 CString 클래스가 존재한다. CStringT 템플릿 클래스의 특정 템플릿 인자로 만들어진 CAtlString typedef된 클래스로 atlstr.h 파일에 선언되어 있다.
이렇게 WTL을 사용하는 ATL 프로젝트에서는 CString에 대해서 ambiguous symbol 에러가 날 수도 있는데 이렇때는 네임스페이스로 해결할 수도 있겠지만 일일이 그렇게 적어 주기는 쉽지 않다.
이럴때 WTL::CString 만 사용하고 싶다면 <atlstr.h> 파일을 빼주면 되겠지만 현재 WTL::CString 보다 ATL::CString 가 기능이 더 많은 것 같다(한 예로 Tokenize() 함수를 들 수 있다). WTL::CString로 할 수 있는 일은 모두 ATL::CString 가 할 수 있어리라 본다. 그리고 ATL::CString 만 사용하고 싶다면 WTL::CString가 선언되어 있는 <atlmisc.h> 파일을 빼주면 되겠지만 MFC가 아닌 환경에서 <atlmisc.h> 파일에 같이 있는 나머지 유용한 클래스(CSize, CPoint, CRect, CFindFile, Atl로 시작하는 전역함수들)를 사용하고 싶다면 그럴 순 없다.

이런 환경에서 ATL::CString를 사용하고 싶다면
첫번째 방법으로는 CString 대신 명시적으로 CAtlCString 란 클래스 명을 사용하면 된다.
두번째 방법으로는 stdafx.h 같은 헤더 파일에 WTL::CString 를 사용하지 않겠다는 선언을 해 주면 된다. 이 선언은 WTL::CString가 선언되어 있는 <atlmisc.h> 파일 위에 선언하면 된다. 그리고 <atlstr.h> 파일은 <atlapp.h> 파일 - 이 파일은 <atlmisc.h> 파일을 사용하기 위해선 먼저 include 하는 파일이다. - 위에 포함되어야 한다.

#include <atlbase.h>
#include <atlstr.h>
#include <atlapp.h>
#define _WTL_NO_CSTRING           // 이곳이나 보다 위쪽에 존재해야 한다.
#include <atlmisc.h>
Posted by 배고파씨