Notice»

Recent Post»

Recent Comment»

Recent Trackback»

Archive»

« 2024/5 »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

 
 
Visual C++ 2005 및 이전 버전의 변경 내용 - MSDN

배포 방법 변경(Redistributable Package - 재배포패키지)과
최신라이브러리 사용
(2008)


1. 2005부터는 배포방법이 바뀌었다.
2. 2008에서는 sp1등의 업데이트를 설치해도 프로젝트 생성시 최신 라이브러리를 기본으로 사용하지 않는다.
 -> _BIND_TO_CURRENT_VCLIBS_VERSION를 미리 선언해야 최신 라이브러리를 사용한다.

위의 두가지 내용은 아래 페이지에 정리해놨음.
VC++ 버전별 배포방법과 재배포패키지(Redistributable Package)

Visual C++ 2005 라이브러리의 변경 사항 - MSDN

CRT 함수의 보안버전
Security-Enhanced Versions of CRT Functions - MSDN

warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

버퍼의 길이체크를 하기 위한 _s접미사가 붙는 보안 버전의 CRT 함수가 추가되었다. 사용방법은 기존 함수에 _s를 붙이고 버퍼의 길이를 인자로 더 추가해주면 된다. 당장은 VC에만 존재하지만 앞으로 C++표준에 추가될 수 있다고 한다.

참고사항
1. _s관련 함수는 errno_t를 반환하게 변경되었다.(에러발생)
2. _CRT_SECURE_CPP_OVERLOAD... 관련 3개의 define을 사용하면 버퍼가 배열형일 경우 Template overloads를 이용해서 기존 코드를 자동으로 _s관련 함수로 변경할 수 있다.

Default 값과 설명
_CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES 1
  -> secure함수에 길이 인자관련을 생략해준다.
_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES 0
  -> 기존함수 지원 ex) strcpy
_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT 0
  -> 길이체크하는 기존함수 지원 ex) strncpy


위와같이 편한 방법이 있지만 포인터형의 버퍼변수 일경우는 기존과 같이 길이값을 인자로 넣어야 한다.
char  a[100];                    // 가능
strcpy_s(a, "hello");
char * p = new char[100]; // 불가능
(컴파일 에러)
strcpy_s(p, 10, "hello");

위와 같은 코드는 혼란만 올뿐이다. 결론은 secure함수를 사용할꺼라면 인자값을 사용하지말고 overload함수도 사용하지 말자.

해결방법
_CRT_SECURE_NO_DEPRECATE를 정의하면 secure함수를 사용하지 않는다.
또는
_CRT_SECURE_NO_WARNINGS 나 #pragma warning( disable : 4996 )를 사용해서
경고만 무시한다.

참고
http://blog.naver.com/kyuniitale?Redirect=Log&logNo=40021387400
C/C++ Secure Function 에 대해서
secure function 쉽게 사용하는 팁


POSIX 호환(compliant)
Deprecated CRT Functions - MSDN
warning C4996: 'stricmp': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _stricmp. See online help for details.

ISO C++의 명명 규칙을 준수하기 위해 POSIX 이름이 이제 사용되지 않는다. 예를 들어, getch 대신 _getch를 사용한다.
보안 함수와 똑같은 4996 경고가 뜬다. 표준이므로 지키자.

해결방법(임시)
_CRT_NONSTDC_NO_DEPRECATE를 정의하거나
#pragma warning( disable : 4996 )를 사용한다.

안전한 문자열 함수(strsafe.h)
Using the Strsafe.h Functions - MSDN
안전한 문자열 함수들(strsafe.h)

warning C4995: 'wsprintf': 이름이 #pragma deprecated로 표시되었습니다.

c/c++ 문자열의 오버플로우를 막기 위해 MS가 제공하는 방안으로 strsafe.h를 선언해서 관련 함수를 사용할 수 있다.

해결방법
#define STRSAFE_NO_DEPRECATE를 정의하거나
#pragma warning(disable : 4995)를 사용한다.

time_t
Time Management - MSDN
time_t가 기본 64비트로 변경되었다. (기존 32비트로 3000년까지만 처리 가능했던걸 확장)

실제선언코드
// VC6
// c:\Program Files\Microsoft Visual Studio\VC98\Include\TIME.H

#ifndef _TIME_T_DEFINED
typedef long time_t;        /* time value */
#define _TIME_T_DEFINED     /* avoid multiple def's of time_t */
#endif

/////////////////////////////////////////////////////////////////////////
// VC9(2008)
// c:\program files\microsoft visual studio 8\vc\include\crtdefs.h

#ifndef _TIME64_T_DEFINED
#if     _INTEGRAL_MAX_BITS >= 64
typedef __int64 __time64_t;     /* 64-bit time value */
#endif
#define _TIME64_T_DEFINED
#endif

문제점

이부분은 기존 long형으로 처리되던 부분들이 에러없이 자동으로 64비트로 변경되므로 32비트로 처리되던 코드들은 메모리주소가 밀려서 쓰레기값으로 처리될수 있다.

해결방법(임시)
_USE_32BIT_TIME_T 를 정의한다.
MSDN을 참고해보면 위와 같이 define해놓으면 time_t를 32비트로 쓸수 있다.

사용자 정의(User-Defined) 메세지

User-Defined Handlers - MSDN
아래 내용은 기존에 정의되어 사용되고 있던 것이지만 VC6에서 대충 넘어가던것을 2005부터는 정확하게 사용되어야 하는 것들이다.

1. ON_MESSAGE
MFC에서 사용자 정의 메세지를 사용시 User-Defined Handlers의 원형은 아래와 같은데
afx_msg LRESULT memberFxn( WPARAM, LPARAM );
VC6에선 반환값을 void형으로 선언하고 사용해도 문제가 없었지만 2005부터는 컴파일 에러가 발생한다

해결방법
1.
ON_MESSAGE를 ON_MESSAGE_VOID로 변경한다.
 -> AFXPRIV.H에 선언되어 있는 ON_MESSAGE_VOID를 사용하면 문제는 해결할 수 있지만 AFXPRIV.H파일 자체가 MFC 버젼이 바뀔경우 예고없이 바뀔 수 있는 파일이므로 조심해야하고 위매크로를 사용시 함수의 인자값이 이상하다는 글을 본적이 있으므로 사용시 주의하자. 매크로의 선언은 아래와 같다.(VC6,2008 sp1)
// like ON_MESSAGE but no return value
#define ON_MESSAGE_VOID(message, memberFxn) \
    { message, 0, 0, 0, AfxSig_vv, \
        (AFX_PMSG)(AFX_PMSGW)(void (AFX_MSG_CALL CWnd::*)(void))&memberFxn },
2. LRESULT를 반환하게 함수를 변경한다.
 -> 이게 표준이니 이렇게 사용하자.


2. ON_THREAD_MESSAGE
ON_THREAD_MESSAGE - MSDN
CWinThread를 상속한 클래스내에서는 ON_MESSAGE가 아닌 ON_THREAD_MESSAGE를 사용해야한다.
사용법은 동일하지만 함수원형에 반환 값이 없다.
afx_msg void memberFxn( WPARAM, LPARAM );

매크로의 선언을 비교해보자.(AFXMSG_.H)
// for Windows messages
#define ON_MESSAGE(message, memberFxn) \
    { message, 0, 0, 0, AfxSig_lwl, \
        (AFX_PMSG)(AFX_PMSGW)(LRESULT (AFX_MSG_CALL CWnd::*)(WPARAM, LPARAM))&memberFxn },

// for Thread messages
#define ON_THREAD_MESSAGE(message, memberFxn) \
    { message, 0, 0, 0, AfxSig_vwl, \
        (AFX_PMSG)(AFX_PMSGT)(void (AFX_MSG_CALL CWinThread::*)(WPARAM, LPARAM))&memberFxn },

Visual C++ 2005 컴파일러, 언어 및 도구의 변경 내용

for 루프 범위의 강제 규칙
/Zc:forScope(for 루프 범위의 강제 규칙) - MSDN
/Zc:forScope가 기본적으로 활성화되어 있다. 이부분은 VC6에서 비표준으로 지원 되던 부분의 수정이므로 표준을 준수하자.

해결방법(임시)
속성 -> 구성속성 -> C/C++ -> 언어 -> For 루프 범위 강제 규칙 -> 아니요
또는 #pragma conform(forScope, on) ,
컴파일 옵션에 /Zc:forScope
위방법중 하나를 선택하면 되겠다.

wchar_t
/Zc:wchar_t(wchar_t를 네이티브 형식으로 인식) - MSDN
/Zc:wchar_t가 기본적으로 사용된다.

속성 -> 구성속성 -> C/C++ -> 언어 -> wchar_t를 기본 제공 형식으로 처리 -> 아니요

error C2668(함수 오버로드)
함수 오버로드에 대한 묵시적 형변환을 사용할 수 없다. VC6에선 상관없던 코드가 최신툴에선 error를 발생한다.

error C2668: 'pow' : 오버로드된 함수에 대한 호출이 모호합니다.
error C2668: 'sqrt' : 오버로드된 함수에 대한 호출이 모호합니다.

위의 에러는  double pow(double x, double y)인 pow함수등을 pow(2,2)같이 호출했을때 발생한다. 이때는 형변환을 하거나 숫자뒤에 '.'를 표시해서 실수로 만들어준다. 표준이므로 지키자.

※표준 준수를 더욱 강화하기 위해 pow의 오버로드 double pow(int, int)가 제거되었습니다. - MSDN
-> int형의 인자를 받던 pow함수가 제거되었다. 그리고
_Pow_int라는 템플릿함수가 추가되었다.


VC 프로젝트 기본 설정

WINVER 설정
VC6프로젝트를 2005이상으로 업그레이드시 WINVER 가 정의 되지 않아 Default 값을 설정한다는 메세지를 볼수 있다.

WINVER not defined. Deafaulting to 0x0502 (Windows Server 2003)
-> 2008은 Vista가 기본이다.

VS2005이상으로 프로젝트를 새로 생성시는 stdafx.h에 #include "targetver.h"가 선언되며 이곳에 프로젝트가 최소로 지원하는 플랫폼을 정의해놨다.

참고
WINVER값이 잘못설정되어 있으면 API나 라이브러리에서 윈도우의 버젼이 잘못 설정되어 이상하게 동작하거나 에러가 발생할 수도 있으므로 업데이트 후 WINVER관련을 잘 체크하자.
->_WIN32_WINNT값을 0x0500으로 선언하고 필자의 경우 CFileDilog를 사용하면 error가 발생한다. 이유는 OPENFILENAME구조체의 선언때문인데 아래 링크를 참조하자.
MFC 프로젝트를 Visual C++ .NET 이나 대상 운영 체제에서 Visual C++ 2005 변경 이식 - MSDN

해결방법
Using the Windows Headers - MSDN

What's the difference between WINVER, _WIN32_WINNT, _WIN32_WINDOWS, and _WIN32_IE? (구글번역)
-> 윈도우 버젼관련 매크로가 아래와 같이 진행되어온 과정을 설명해준다.(참고)

WINVER _WIN32_WINNT _WIN32_WINDOWS Product release
0x0400 not used 0x0400 Windows 95
0x0400 not used Windows NT 4.0
0x0410 not used 0x0410 Windows 98
0x0500 not used 0x0500 Windows Me
0x0500 not used Windows 2000
0x0501 0x0501 not used Windows XP
0x0502 0x0502 not used Windows Server 2003
0x0600 0x0600 not used Windows Vista

아래코드를 stdafx.h의 젤 윗부분에 선언해주면 되며 설정값을 변경하고 싶으면 위 MSDN링크를 참고한다.
#ifndef WINVER 
    #define WINVER 0x0400 
#endif                              

#ifndef _WIN32_WINNT  
    #define _WIN32_WINNT 0x0400 
#endif                        

#if (_MSC_VER > 1200) 
    #ifndef _WIN32_WINDOWS 
        #define _WIN32_WINDOWS 0x0410
    #endif
#endif    // _MSC_VER     

#ifndef _WIN32_IE   
    #define _WIN32_IE 0x0400 
#endif                              

Hotfix

912790
http://support.microsoft.com/kb/912790
2005의 버그인데 2008에도 똑같이 존재한다.

ANSI로 인코딩된 소스코드를 VS.NET 2005 (한글판)에서 빌드하면서 발생하는 문제로 일본판의 경우에도 비슷한 문제가 발생하였고 영문판 VS.NET 2005에서는 발생하지 않는 것으로 알려져있다. 그냥 무시해도 무방할 듯 하다.

해결방법
#pragma warning(disable: 4819) // <- 이 부분을 소스에 추가하거나.

2005버전 이상인 경우는 프로젝트 옵션에서
"프로젝트->속성->구성속성->C/C++->고급->특정 경고 사용 안함" 에 4819를 넣어주거나.

'파일->저장 고급 옵션'
"유니코드 - 코드페이지 1200" 형태로 저장하면 된다.


참고
http://blog.naver.com/khs01016?Redirect=Log&logNo=44587778
http://www.killereco.pe.kr/134


99%'s Code
위 정리된 사항을 필자는 아래코드로 헤더파일 하나에 넣고 stdafx의 상위에서 설정해서 사용한다.
sy는 필자 이름이므로 헷갈리지 말자 ㅎㅎ
// syDef.h

#pragma once

///////////////////////////////////////////////////////////////////////////////////////////////////////////
// 최소로 지원하는 플랫폼 정의

// Modify the following defines if you have to target an OS before the ones
// specified in the following code. See MSDN for the latest information
// about corresponding values for different operating systems.
#ifndef WINVER                // Permit use of features specific to Windows 95 and Windows NT 4.0 or later.
#    define WINVER 0x0400  // Change this to the appropriate value to target
#endif                        // Windows 98 and Windows 2000 or later.

#ifndef _WIN32_WINNT            // Permit use of features specific to Windows NT 4.0 or later.
#    define _WIN32_WINNT 0x0400    // Change this to the appropriate value to target
#endif                            // Windows 98 and Windows 2000 or later.          

#if (_MSC_VER > 1200)    // VC6 초과
#    ifndef _WIN32_WINDOWS                // Permit use of features specific to Windows 98 or later.
#        define _WIN32_WINDOWS 0x0410    // Change this to the appropriate value to target
#    endif
#endif    // _MSC_VER                        // Windows Millennium Edition or later.

#ifndef _WIN32_IE                // Permit use of features specific to Internet Explorer 4.0 or later.
#    define _WIN32_IE 0x0400    // Change this to the appropriate value to target
#endif                            // Internet Explorer 5.0 or later.

// #include "targetver.h" -> .net툴에서 위코드가 포함된 헤더파일
// http://msdn.microsoft.com/en-us/library/aa383745(VS.85).aspx - Using the Windows Headers(MSDN)


///////////////////////////////////////////////////////////////////////////////////
// Visual C++ 8이상 세팅

//#define SYUTIL_USE_CRT_SECURE        // CRT 보안관련 함수 사용
#define SYUTIL_NOTUSE_NONSTDC_NO    // POSIX관련 CRT사용안함
#define SYUTIL_USE_32BIT_TIME_T        // time_t를 32비트로 사용함

// VC8(VS2005) 이상 컴파일러설정.
#if defined(_MSC_VER) && (_MSC_VER >= 1400)

    // 최신버젼의 VC라이브러리 사용
    // Redistributing an Application and Binding It to Specific Libraries - MSDN
    // http://msdn.microsoft.com/en-us/library/cc664727.aspx
#    ifdef _BIND_TO_CURRENT_VCLIBS_VERSION
#        undef _BIND_TO_CURRENT_VCLIBS_VERSION
#        define _BIND_TO_CURRENT_VCLIBS_VERSION 1
#    else
#        define _BIND_TO_CURRENT_VCLIBS_VERSION 1
#    endif

    // CRT 보안관련 라이브러리 설정
    // Security-Enhanced Versions of CRT Functions - MSDN
    // http://msdn.microsoft.com/ko-kr/library/wd3wzwts.aspx
#    ifdef SYUTIL_USE_CRT_SECURE
#        define _CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES            0
#        define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES            0
#        define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT    0
#    else
#        ifndef _CRT_SECURE_NO_DEPRECATE
#            define _CRT_SECURE_NO_DEPRECATE
            //#define _CRT_SECURE_NO_WARNINGS
            //#pragma warning(disable : 4996)
#        endif
#    endif // SYUTIL_USE_CRT_SECURE

    // POSIX관련 CRT 사용
    // Deprecated CRT Functions - MSDN
    // http://msdn.microsoft.com/en-us/library/ms235384.aspx
#    ifdef SYUTIL_NOTUSE_NONSTDC_NO
#        ifndef _CRT_NONSTDC_NO_DEPRECATE
#            define _CRT_NONSTDC_NO_DEPRECATE
            //#pragma warning(disable : 4996)
#        endif
#    endif // SYUTIL_USE_NONSTDC_NO

    // 안전한 문자열 사용(오버플로우 방지)
    // Using the Strsafe.h Functions
    // http://msdn.microsoft.com/ko-kr/library/ms647466(en-us,VS.85).aspx
#    define STRSAFE_NO_DEPRECATE
    //#pragma warning(disable : 4995)

    // time_t 64비트 처리
    // Time Management - MSDN
    // http://msdn.microsoft.com/ko-kr/library/w4ddyt9h.aspx
#    ifdef SYUTIL_USE_32BIT_TIME_T
#        define _USE_32BIT_TIME_T
#    endif // SYUTIL_USE_32BIT_TIME_T

    // 유니코드 형식으로 저장하라는 경고 무시 -> VS 버그임
    // http://support.microsoft.com/kb/912790
#    pragma warning(disable: 4819)
#endif // _MSC_VER



정리중...

///////////////////////////////////////////////////////////////////////////////////////////////////////
// 문자 집합이 기본 유니코드이다.
속성 -> 구성속성 -> 일반 -> 프로젝트 기본값에서 문자 집합 -> 멀티코드 문자 집합 사용

///////////////////////////////////////////////////////////////////////////////////////////////////////
// 런타임라이브러리(CRT)이 기본 /MD, CRT라이브러리에 대해서는 고민해보아야 하고
// 기존라이브러리들과 맞춰주는게 좋다.
속성 -> 구성속성 -> C/C++ -> 언어 -> 런타임 라이브러리 -> /MT

///////////////////////////////////////////////////////////////////////////////////////////////////////
// 비증분 링크
LINK : warning LNK4076: '.\Debug/IIS.ilk' 증분 상태 파일이 잘못되었습니다. 비증분 링크합니다.

프로젝트 -> 속성 -> 링커 -> 일반 -> 증분 링크 사용 -> 아니요(/INCREMENTAL:NO)

///////////////////////////////////////////////////////////////////////////////////////////////////////
// 증분 링크
LNK4075: '/EDITANDCONTINUE'이(가) '/INCREMENTAL:NO' 사양으로 인해 무시됩니다.

프로젝트 -> 속성 -> 링커 -> 일반 -> 증분 링크 사용 -> 예(/INCREMENTAL)

증분링크란?
obj를 합치는과정에서 메모리배치랑 순서 함수들 코드, 데이터 영역등을 계산하게 되는데 이걸 매번 재계산하게되면 시간이 오래 걸리게되죠
그래서 변한건만 재계산하는 과정을 말합니다. 위의 속성은 "증분 링크" 하겠다는거죠.간간히 이전obj가 껴있어 문제가 생기는데
이땐 rebuild all해서 풀링크 하면된다고 하네요 ^^;;
 
http://cafe.naver.com/bit1004/554
http://blog.naver.com/amoros21?Redirect=Log&logNo=140061746992
http://blog.naver.com/blue7water?Redirect=Log&logNo=10051860035
http://hongyver.pe.kr/ttblog/entry/VC6-%EC%97%90%EC%84%9C-VS2005%EB%A1%9C-%EC%98%AE%EA%B8%B0%EA%B8%B0
:
배포시에는 Dependency Walker(depends.exe)와 같은 도구를 사용하여 종속 DLL의 목록을 확인한다. 또한 2005이상의 VS(Visual Studio)는 manifest를 꼭 확인해서 사용한 dll과 버전을 확인해야한다.

VC++ Library
그림 1(VS2005 기준)

그림은 VS2005를 기준으로 하고 있지만 다른 버젼도 위와 같은 규칙으로 명명되고 있다. xx는 각각의 버전을 나타내며 플랫폼 별로 x86,ia64,x64용이 따로 있다. u는 Unicode버전을 나타내고 m은 managed code를 사용했을때 사용되며 배포시 .NET Framework이 필요하다. 배포폴더에 manifest가 존재하면 같이 배포한다.

참고
Visual C++ Libraries as Shared Side-by-Side Assemblies - MSDN


컴파일러와 라이브러리의 버젼을 나타내는 매크로

Predefined Macros - MSDN

_MSC_VER(MS 컴파일러)

  Visual Studio 4.0  1000
  Visual Studio 5.0  1100
  Visual Studio 6.0  1200
  Visual Studio .NET 2002  1300
  Visual Studio .NET 2003  1310
  Visual Studio 2005  1400
  Visual Studio 2008  1500

_MFC_VER(MFC 버젼)

 Visual Studio 6.0   0x0600
 Visual Studio .NET 2002   0x0700
 Visual Studio .NET 2003  0x0710
 Visual Studio 2005  0x0800
 Visual Studio 2008  0x0900

_ATL_VER(ATL 버젼)

 Visual Studio 6.0   0x0300
 Visual Studio .NET 2002   0x0700
 Visual Studio .NET 2003  0x0710
 Visual Studio 2005  0x0800
 Visual Studio 2008  0x0900


VC 6 이하(~ VS6)
VC6관련 DLL은 98이후부터는 운영체제에 포함되어 있다. 그러므로 현재는 배포시에 거의 문제될게 없다.

참고
ActiveX 배포를 위한 cab파일(MS) - inf파일에 링크를 추가해준다.
Vcredist.exe로 Visual C++ 응용 프로그램용 최신 런타임 구성 요소가 설치된다 - MSDN고객지원

VC 7.1(VS 2003)
VC7.1관련 DLL은 최신 운영체제라고 해서 더는 기본 내장을 해주지않기 때문에 응용 프로그램이 알아서 자기 디렉터리나 윈도우 시스템 디렉터리에다 구비해야 한다.



VC 8이후(VS 2005~)

Side by Side Asembly
2005부터는 side by side asembly라는 기술이 도입되어 VC관련 라이브러리들이 Windows 디렉토리 밑에 WinSxS (Windows Side-by-Side)라는 공유 폴더(native assembly cache)로 관리된다. side by side asembly는 DLL 충돌문제를 해결해서 각각의 어플리케이션에게 독립적인 DLL환경을 제공하기 위한것으로 여러버젼의 DLL들이 등록될수 있다. 복잡한 이과정을 간단하게 해결하는 방법으로 VC8부터는 재배포 패키지(Redistributable Package)라는 배포용 설치파일이 도입되어 공용 라이브러리를 자동으로 설치/등록해준다. 또한 프로젝트에서 자동 생성해주는 Manifest Flie에 사용된 DLL과 버전이 자동으로 입력되니 배포시는 꼭 확인하도록 한다.
프로그래머나 사용자입장에선 관련 DLL을 포함만 하면 되는 기존 작업과 달리 설치파일이 하나 더생겼으니 귀찮은 작업이지만 최신 운영체제의 기본 관리 방법이기도 하고 .Net의 기술과도 무관하지 않으니 지금 정리하도록 하자.


최신 라이브러리를 Manifest에 기술하기(VC9)
배포방법을 알아보기 전에 알아두어야 할사항이 있다. VC9는 VC8과 달리 sp1같은 최신 라이브러리를 개발자PC에 설치했다고 해도 프로젝트가 최신라이브러리를 사용한다고 명시해주지 않으면 기존라이브러리를 기본으로 사용하므로 주의해야한다. 이것은 개발자가 sp1을 설치했어도 프로젝트는 기존 DLL버전을 사용하므로 배포시 sp1용 재배포 패키지를 사용하면 제대로 실행될 수 없음을 나타낸다. 방법은 아래와 같다.

'_BIND_TO_CURRENT_VCLIBS_VERSION'를 프로젝트 설정에서 선언해준다.
-> stdafx.h의 상단에 #define으로 입력해도 일반적인 프로젝트에선 상관없지만 프리컴파일드 헤더를 사용안하거나 외부라이브러리가 프로젝트에 미리 세팅되었을 경우 두개의 버전을 중복 사용하는 경우가 발생할 수 있으므로 프로젝트 설정에서 선언하길 권장한다. 이값은 CRT,MFC,ATL,OPENMP 4개의 '_BIND_TO_CURRENT...' 선언을 다 쓰겠다고 선언하는것이고 _BIND_TO_CURRENT_VCLIBS_VERSION의 기본값은 0으로 세팅되어있다.


참고

응용 프로그램 재배포 및 특정 라이브러리에 바인딩 - MSDN

최신 라이브러리를 메니페스트에 기술하기


배포방법
그림1과 참고에 MSDN링크가 2005의 공용DLL 목록과 설명이다. side by side asembly로 인해 배포문제가 좀 복잡해져서 depends 만을 확인해서 관련 DLL을 포함한다고 제대로 실행된다는 보장을 받을 수 없게되었다. 일반적인 방법과 재배포 패키지를 사용하는 방법을 알아보자.

1. 정적 라이브러리(Static Library)를 사용한다.
실행파일이 커지긴 하나 제일 간단하다. MFC 라이브러리를 사용시는 MFC라이브러리를 정적으로 포함하면 CRT도 자동으로 /MT로 변경된다. 용량은 기본 MFC 다이얼로그 프로젝트가 52k정도에서 308k 정도로 커진다.
ATL과 OPENMP까지 사용한다면 웹에서 배포되는 ActiveX 같은 상황이면 용량때문에 고민해봐야할 문제이고 정적라이브러리도 동적라이브러리와 똑같다고는 하지만 몇가지 버그가 있으므로 주의하자.

참고
MFC Static으로 소켓사용시..

2. Manifest를 참조해서 기본 DLL을 배포한다.(Private Assembly)
배포방법이 바뀌었다곤 하나 관련 DLL을 포함해서 배포할수도 있다. VS의 설치폴더에 있는 공용DLL(Private Assembly)을 같이 배포하면 된다. 우선 Manifest로 사용한 DLL을 확인한후 "..\Microsoft Visual Studio X\VC\redist\"에서 관련 DLL(그림1참고)을 프로젝트 폴더에 포함한다. 이방법도 쉬운편이긴 하나 3MB정도의 크기인 재배포 패키지에 비하면 사용하는 라이브러리가 많을 수록 용량이 너무 큰편이다.(기본 CRT와 MFC라이브러리만 4.76MB - 2008sp1 기준)

3. 인스톨쉴드(Install Shield), 설치 프로젝트를 이용해서 재배포 패키지가 자동으로 설치되게 한다.
 -> 모든 프로젝트를 이렇게 만들긴 좀 귀찮다;;

4. .Net Framework(최신)를 설치한다.
.Net Framework를 설치하면 CRT관련 DLL만 같이 설치된다.(fx 3.5설치시 8.0과 9.0이 같이 설치됨)
managed로 컴파일했다면 .Net Framework는 필수이므로 고민할 문제가 아니지만 용량이 100메가도 훨씬 넘는다..;;

5. 재배포 패키지 - 아래에서 따로 설명한다.

위 방법 외에도 몇가지가 더 있으며 아래링크를 참조하기 바란다.
RedistributingVisualCppRunTimeLibrary
Bootstrapper for the VC++ 2005 Redists (with MSI 3.1) - codeproject

재배포 패키지(Redistributable Package)
재배포 패키지는 Windows Installer 3.1을 필요로 하는 인스톨 파일이다. 한번 실행하기만 하면 자동으로 설치되지만 사용자 입장에선 불편한 사항이다. 하지만 Windows Installer의 Command line을 이용해서 몰래설치하는 방법이 있다. 이를 이용해서 런처형식의 프로그램을 만들면 Windows Installer 3.1의 설치유무와 재배포 패키지 자동 설치를 하고 프로그램을 실행하게 할 수 있다. 좀더 범용적으로 사용하면 파일로 설치필요 설정값을 받아와서 COM관련 등록이나 웹배포시 ActiveX등록등을 자동으로 하게 만들수도 있다. 관련 소스가 정리되는 대로 블로그에 올리도록 하고 우선 VC6으로 재배포 패키지의 설치유무와 자동 실행하기 위한 코드를 설명하겠다.

1) 재배포 패키지 설치 유무 확인
재배포 패키지는 설치폴더에서 받거나(..\Microsoft Visual Studio X\SDK\v2.0\BootStrapper\Packages\vcredist_x86) 아래 링크를 통해 MS의 다운로드에서 받는다.

2-1) 일반 적인 인스톨러 사용처럼 추가/제거 목록에 표시되므로 레지스트리 값으로 확인할 수 있다.
"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\ProductCode"

2-2) MsiQueryProductState API를 이용해서 확인한다.
리턴값으로 INSTALLSTATE_DEFAULT인지만 확인하면 설치유무를 판단할 수 있다.

위 2개의 방법에서 모두 필요한 ProductCode는 아래와 같다.

Visual C++ 2005 runtime files

Visual C++ 2005 SP1 runtime files

Visual C++ 2008 runtime files

Visual C++ 2008 SP1 runtime files

위코드는 영문 버전이고 한글버전은 다르고 설치시 중복될수 있다. ProductCode와 추가/제거에 표시되는 이름외에 다른점은 없다. 참고로 2008 sp1 x86 한글버전은 {887868A2-D6DE-3255-AA92-AA0B5A59B874}이다.
Window7에서도 테스트 했음.

참고
How to detect the presence of the VC 8.0 runtime redistributable package
How to detect the presence of the Visual C++ 9.0 runtime redistributable package
NSIS로 VC8.0 Redistributables 체크방법
MsiQueryProductState를 통한 VC 2005 Redistribute 라이브러리 설치체크 방법


2) 재배포 패키지 몰래 설치하기(Command Line)
명령행으로 실행시 Windows Installer 로 만들어진 패키지는 /?로 명령어 종류를 볼수 잇다.

VS2005
VC2005의 경우는 재배포 패키지가 VS기본 폴더에 존재하는 설치파일과 웹에서 받은 파일이 좀 다른데 웹에서 받은 재배포 패키지의 경우 압축이 한번더 되어있어서 인자값 설정 방법이 다르다. 또한 압축이 몇번에 걸쳐 되어있으므로 한글로 계정이 되어있어 한글 경로가 있을 경우 잘 설치가 안될수도 있다. 필자는 2008을 사용하므로 2005에 대한 사항은 관련 링크로 정확한 정보를 얻자.
How to perform a silent install of the Visual C++ 8.0 runtime files (vcredist) packages
- VS기본 폴더에 포함된 재배포 패키지 설치
VC 8.0 런타임 (vcredist) 패키지 몰래 인스톨하기 - 웹에서 받은 재배포 패키지 설치(번역)
Visual C++ 2005 재배포 패키지가 설치안될때



VS2008
2008에서는
<full path>\vcredist_x86.exe /qb
<full path>\vcredist_x86.exe /qb!
<full path>\vcredist_x86.exe /q   -> 화면에 전혀 보이지 않음
위 3가지 방법중 선택해서 사용하면 되며 Vista이상의 경우는 /q로 설정해도 UAC가 보이므로 필자는 /qb!를 사용한다. 직접 사용해보고 판단하자.

참고
How to perform a silent install of the Visual C++ 2008 redistributable packages

99%'s Code
위 재배포 패키지 몰래설치하기 코드를 간단하게 정리했음.

1. 설치유무 판단후 재배포 패키지를 설치하고 원하는 파일을 실행한다.
 // 2008 sp1
    CString csProduct = "{887868A2-D6DE-3255-AA92-AA0B5A59B874}";  
//{9A25302D-30C0-39D9-BD6F-21E6EC160475}

    INSTALLSTATE t = MsiQueryProductState(csProduct);
    if(INSTALLSTATE_DEFAULT != t)
    {
        AfxMessageBox("재배포 패키지를 설치하겠습니다.");
 //    WinExec("vcredist_sp1_x86.exe /q",SW_SHOW);
        WinExec("vcredist_sp1_x86.exe /qb!",SW_SHOW);
        AfxMessageBox("설치 완료");
 // xp에선 설치완료후 정확하게 뜨지만 Windows7에선 완료되지 않았는데 뜬다.
    }
    else
        AfxMessageBox("이미 설치됨");
  
    // 아래 레지스트리값의 유무로 판단할수도 있다.(win7에서도 똑같다.)
    //HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{887868A2-D6DE-3255-AA92-AA0B5A59B874}
  
    while(INSTALLSTATE_DEFAULT != MsiQueryProductState(csProduct))
        Sleep(30);
    WinExec("test.exe",SW_SHOW);    // 원하는 프로그램 실행
2. 제거
    WinExec("vcredist_sp1_x86.exe /qu",SW_SHOW);
    AfxMessageBox("제거 완료");

:
현재 2009년 7월 기준으로 최신 버젼은 1.1pre1이다.
아직 정식버젼이 아니고 '오픈소스 OpenCV를 이용한 컴퓨터 비전 실무 프로그래밍' 책을 기준으로 정리하므로 1.0을 기준으로 정리한다.

http://sourceforge.net/projects/opencvlibrary/ - 소스포지
http://opencv.willowgarage.com/wiki/ - OpenCV Wiki(문서)
http://tech.groups.yahoo.com/group/opencv/ - 야후 그룹스
http://www.opencv.co.kr/  - 우리나라 최대 커뮤니티
http://opencv.jp

oepncv.jp의 docs- 번역해서 한글로 보기
OpenCV docs - 검색가능
OpenCV docs - conv2(설치폴더의 docs)

다운로드
http://sourceforge.net/projects/opencvlibrary/files/ 에서 open-cv -> 1.0 -> OpenCV_1.0.exe를 다운받는다.

설치
받은 파일을 실행해서 설치한다. 기본설정은 C:\Program Files\OpenCV으로 되어있으며 설치파일은
폴더를 환경변수에 Path등록과 bin폴더안에 calibfilter.ax,proxytrans.ax,syncfilter.ax 3개의 Activex를 등록한다.
registerall.bat를 이용하면 엑티브엑스 3개는 자동등록된다.

사용하기

1. 디버깅정보를 얻기위해서 다시 컴파일 해야된다. 설치폴더안에 _make폴더에서 opencv.dsw를 실행한다.

* Batch Build에서 필요한것만 체크하자.

cvaux.h파일의 1137 Line에서 주석처리를 잘못해서 에러가 난다.
//수정전
   CvMemStorage*   storage;      /*storage for 밼oreground_regions\/              \
//수정후
   CvMemStorage*   storage;      /*storage for Foreground_regions*/                \
위와같이 변경하고 컴파일하면 성공.


2. VC개발환경에 OpenCV의 헤더파일, 라이브러리 폴더를 설정해준다.

Tool -> Option -> Directory

Include에
C:\PROGRAM FILES\OPENCV\CV\INCLUDE
C:\PROGRAM FILES\OPENCV\CVAUX\INCLUDE
C:\PROGRAM FILES\OPENCV\CXCORE\INCLUDE
C:\PROGRAM FILES\OPENCV\ML\INCLUDE
C:\PROGRAM FILES\OPENCV\OTHERLIBS\CVCAM\INCLUDE
C:\PROGRAM FILES\OPENCV\OTHERLIBS\HIGHGUI

Library에
C:\PROGRAM FILES\OPENCV\LIB


3. DLL 구성

DLL파일은 총 7개이고 C:\Program Files\OpenCV\bin에 존재한다.
환경변수로 설정했을 경우 사용자는 배포시에만 필요 dll을 포함하면된다.

보통 3~5개의 dll이 사용되며
영상을 읽고, 변환하고, 보여주는 함수만 사용하면 cv100.dll, cxcore100.dll, highgui100.dll만 있으면된다.

53Page

libquide40.dll은 OpenMP라이브러리이다.

샘플프로그램
설치폴더에 samples\c에 존재하며 이와는 다르게 tests라는 폴더는 cv,cxcore라이브러리 내 주요 함수를 검증하기 위한 테스트 코드도 존재한다.


55Page

CvvImage 클래스

highgui.h에 선언되어 있다. 유일하게 dc를 사용하는 클래스.

193Page

MS VS2003부터 ATL에 Cimage라는 클래스가 추가되었으며 CvvImage와 구조가 비슷하다.
CImage는 C#의 그래픽 엔진인 GDI+를 Wrapping한 클래스이다.

CImage - MSDN

GDI+ (& CImage) - 99%의 정리

코너, 외곽선, 에지 설명(p.142)

정성호,이문호님의 책 예제
※ 소스삭제 -> 소스는 저작권이 있으므로 책을 사서 정리된 내용을 참고하시길..

ConsoleCV First.zip

-> Chapter1까지의 간단예제

ConsoleCV.zip

-> Chapter2와 Chapter6(cvcam)의 첫부분 예제. 함수마다 페이지를 적어놨음.

OpenMFC MFC첫 사용예제(4장).zip

-> Chapter4. MFC 처음 사용예제( CvvImage를 이용한 영상 읽기,저장,출력<From DC>, 클립보드<DIB>, 로그창)

OpenMFC_5장.zip

-> Chapter5 예제(RGB 컬러공간분리, 공간영역필터링<필터기술>, HBitmap으로 변환후 Picture컨트롤에 출력, CvvImage버퍼를 이용한 취소,복원기술)

OpenMFC_6장.zip

-> Chapter6 예제(cvcam를 사용, facedetect예제와 ConsoleCV의 간단 예제를 이용해서 얼굴 추출을 구현한 예제)

facedetect.zip

-> 얼굴추출소스<444Page>, 6장 예제의 기본소스
(OpenCV 기본 Sample폴더에 있는 facedetect예제에 저자가 주석을 달아서 정리한것이다.)


참고
오픈소스 OpenCV를 이용한 컴퓨터 비전 실무 프로그래밍 : 기본편 - 정성호,이문호 저
http://www.conv2.com/ - 이문호님 홈페이지(OpenCV)

opencvGIF
-> OpenCV 에는 GIF가 없다. 적용하고 싶을때 사용.

Easy to use Wrapper (DLL) for Intel's OpenCV Library with Examples
-> C#용 Wrapper DLL

c#으로 OpenCV하기 카페


VC의 Profiling(프로파일링) 사용과 수행시간 측정 함수사용법(CRunTimeChk)
-> CxImage책의 p.106을 참고. OpenCV책의 p.266을 보면 OpenCV 라이브러리를 이용한 방법도 소개하고 있다.

'프로그래밍 > 영상, 음성' 카테고리의 다른 글

CxImage  (0) 2009.08.19
GDI+ (& CImage)  (0) 2009.07.23
영상처리 관련 조언, 책들...  (0) 2009.07.20
IJL(Intel Jpeg Library)  (1) 2009.04.16
:

CxImage

프로그래밍/영상, 음성 | 2009. 8. 19. 14:27 | Posted by 99%
http://www.xdp.it/cximage.htm
http://www.codeproject.com/KB/graphics/cximage.aspx

함수 레퍼런스
http://www.xdp.it/cximage/

메소드 요약(한글요약)
http://katalog.egloos.com/2626276

소개

- Davide Pizzolato가 개발한 영상 처리 라이브러리.
- 2001년도 코드 프로젝에서 시작하여 오픈소스로 성장.
- 플랫폼에 종속적이지 않고 무료이다.(win,linux,wince 등)

- C++클래스로 설계되어 있으며 영상 읽기, 저장, 보기, 영상 변환 등을 구현해놨고 Image resource, File, Memory 로 생성이 가능하다.
- BMP,GIF,ICO,TGA,PCX,WBMP,WMF 가 지원되고, 그외 JPEG, PNG, MNG, TIFF 등의 포멧들은 추가 라이브러리가 필요하다. TIFF, JPEG, PNG, ZLIB, J2K 오픈 라이브러리와 연계되어 있음.
-
배포형식이 full과 lite가 있는데 lite는 CxImage 소스만을 포함하고 있으며, full에는 다른 포멧이 요구하는 라이브러리가 (jpeg, png, zlib, 등등) 포함되어 있다.


클래스 구조 -(정성호,이문호 님의 책 p.120)



설치
  1. 다운로드에서 최신버젼을 받는다.
    -> 현재 09년 7월 6.0이 최신이며 VS최신 .Net툴을 지원했다 안했다 한다;
  2. 플젝을 불러와서 컴파일한다.
    1. CxImage - 정적 라이브러리
      -> 사용시 영상 포맷관련 라이브러리도 가져와야한다. j2k.lib,jasper.lib 등..
    2. CxImageCrtDll - 정규 DLL
      -> cximagecrt.lib, cximagecrt.dll
    3. CxImageMfcDll - 정규 DLL, MFC사용(거의 사용한 흔적이 없다. 왜 이렇게 제공할까? ㅡ.ㅡ;)
      -> cximage.lib, cximage.dll
  3. 플젝 폴더에 헤더파일(23개)과 라이브러리 파일을 사용할 프로젝트로 가져와서 설정한다.
    -> #pragma comment(lib,"cximaged.lib")
         #include "xImage.h"
설정방법 및 JPG라이브러리만 사용하기



최신 라이브러리가 제대로 적용안될때(VS2008)


문제점
CxImage 소스를 VC6에서 컴파일하고 VC9로 자동업데이트 했다.(Static Library) VC9에서 sp1을 적용하게 _BIND_TO_CURRENT_VCLIBS_VERSION를 프로젝트 속성에 선언했는데 manifest를 확인해보니 CRT구버젼을 사용한다고 계속 명시되어있다.

확인해보니 이미 업데이트된 프로젝트의 속성에 입력을 해도 각각의 파일에는 그 속성이 적용이 안되고 있었다.

해결방법
VC9프로젝트 파일을 삭제하고 VC6의 프로젝트 속성에서 미리 선언해준후 다시 업그레이드한다.



정성호,이문호님의 책 소스
FirstCxImage.zip(삭제)

-> 위 설치과정이 1장에 해당되는 내용이며 소스는 책 전체의 예제이다.

'프로그래밍 > 영상, 음성' 카테고리의 다른 글

OpenCV(ComputerVision) 기본편  (1) 2009.08.19
GDI+ (& CImage)  (0) 2009.07.23
영상처리 관련 조언, 책들...  (0) 2009.07.20
IJL(Intel Jpeg Library)  (1) 2009.04.16
:
Profile - 분석표라고 정의하는게 맞는것 같다.

Visual C++ Profiling

Visual C++에서는 함수별 실행 시간, 수행 횟수 비율 등 다양한 기능을 보여주는 프로파일링 기능을 제공한다. 참고로 자바에서는 JProfiler, UNIX/Linux에서는 gprof라는 프로그램이 있다.

사용방법

1. Project Setting(Alt+F7) 에서 Ling탭의 Enable profiling을 체크한다.

3. Rebuild(재빌드)한다.

4. Build -> Profile을 선택한다.

5. Profile에서 원하는 값을 선택후 OK를 누른다.

6. 프로그램을 실행후 종료하면
Output창에 Profile이 선택되어 결과가 출력된다.


※ Window2000에서 profile 메뉴가 활성화되지 않는 문제점

Visual Studio가 설치될 때 Profile과 관련된 레지스트리 정보를 HKEY_CURRENT_USER 아래에 써넣는다. 그래서 Visual Studio를 설치할 때 사용했던 계정으로 로그인하지 않으면 profile이 활성화되지 않는다.

이를 해결하려면 VC를 설치할 때 접속했던 계정으로 로그인을 하던가, 아니면 레지스트리에 값을 써넣어주면 된다. 메모장으로 아래의 내용을 복사한후 *.reg파일로 저장한다.(파일이름은 상관없음)

    REGEDIT4
    [HKEY_LOCAL_MACHINE\Software\Microsoft\DevStudio\6.0\General]
    "ProfilerInstalled"=dword:1

이 파일을 더블클릭하면 레지스트리에 값이 써지고 VC에 profile 메뉴가 활성화된다.

이 정보는 MSDN에서 Q224382로 찾아보시면 되겠다.


수행시간 측정

1. clock()
ANSI C 함수이며 time.h에 정의되어 있어 UNIX/Linux에서도 잘 수행된다.
현 프로세스가 실행한지 얼마 되었는지에 대한 CPU 시간을 clock tick의 개수 단위로 반환해준다.

#include "time.h"

// 시작
clock_t beginTime;
clock_t endTime;
beginTime = clock();

// 작업 수행

// 수행 종료
endTime = clock();

// 값 출력
CString tmp = _T("");
tmp.Format("작업 수행 시간 - clock() : %5.3f",
           (double)(endTime - beginTime) / CLOCKS_PER_SEC); 

2. timeGetTime(), GetTickCount()
1/1000초 단위로 정확하게 제어할 수 있는 타이머가 바로 멀티미디어 타이머이다. 자세하게 말한다면 Timer Event Callback Notification 메커니즘을 적용하고 있는 타이머이다. 이 멀티미디어 타이머의 단점은 많이 사용할수록 시스템에 상당한 부하를 일으키며, 이외에 제대로 사용하지 못하면 예측할 수 없는 결과가 초래된다고 알려져있다. 이 타이머는 수행 시간 기준으로 일정한 시간이 되면 어떠한 행동을 취하는데 사용된다.
GetTickCount() 함수와 timeGetTime() 함수의 차이점은 운영체제의 정밀도에 차이가 있다. 예를 들어 GetTickCount()함수는 윈도우 9X에서는 기본으로는 약 55 밀리 초이지만, timeGetTime() 함수는 윈도우 9X에서는 1밀리 초이다. 따라서 부정확해질 수 있다. 그러므로 결국 timeGetTime()을 사용하는 게 유리하다. 다만 두 함수는 윈도우 2000, XP등 으로 올라갈수록 정밀도가 현격하게 벌어지게 된다. 따라서 최소의 타이머 해상도를 결정하는 timeBeginPeriod()함수와 timeBegindPeriod에 의해 만들어진 타이머 해상도를 제거하는 timeEndPeriod() 함수를 추가해 줌으로써 정밀도를 보정해 줄 수 있다. 정확한 시간을 구하지 않는 다는 가정 하에서는 두 함수 중에서 편한대로 선택한다.

#include "Mmsystem.h"
#pragma comment(lib,"winmm.lib")

// 시작
timeBeginPeriod(1);
DWORD tStart,tEnd;
tStart = timeGetTime();
// tStart = GetTickCount();

// 작업수행

// 수행 종료
tEnd = timeGetTime();
// tEnd = GetTickCount();
timeEndPeriod(1);

// 값 출력
CString tmp = _T("");
tmp.Format("작업 수행 시간 - timeGetTime() : %5.3f", (tEnd-tStart)/1000.0); 
 
3. QueryPerformanceCount()
초당 증가값을 주파수(frequency)라고 한다면, 그 값을 구하며 부팅 후 절대로 변하지 않는 방식을 적용한 QueryPerformanceCount() 함수는 7~8백만분의 1초까지 더 정밀하게 구하기 위해 사용한다.
 
// 시작
LARGE_INTEGER frequency, tStart, tEnd;
QueryPerformanceFrequency( &frequency );
QueryPerformanceCounter( &tStart );

// 작업 수행

// 수행 종료
QueryPerformanceCounter( &tEnd );
double tElpased =  \
(double)(tEnd.QuadPart - tStart.QuadPart)/(double)frequency.QuadPart;

// 값 출력
CString tmp = _T("");
    tmp.Format("작업 수행 시간 -  QueryPerformanceCounter() : %5.3f", tElpased); 

CRunTimeChk


위에서 소개한 clock,
QueryPerformanceCount
를 각각 사용해서 수행시간을 체크하는 클래스이다.


참고
CxImage를 이용한 Visual C++ 디지털 영상처리(정성호,이문호) - p.106
:
<자료>방송통신망 기반 IP-USN 통합 시험환경 구축 사업(08.9.~09.1)-현대HDS

<기사>NIA, 방송통신망 + IP-USN 선도 시험환경 구축(09.3.6)-현대HDS 컨소시엄

http://www.g-ipusn.or.kr
-> 국내 구축현황

http://k-m2m.co.kr


홈페이지가 곧 개편된다.

 







NIA본사 IPTV송출 테스트(대전 ICU, 광주 ETRI 장비)


테스트 장비
IP-USN 센서 장비(피코스넷, 한울, 아이비트)
Strix 무선메쉬(OWS)

SNP-1000(삼성테크윈IP카메라)

PLC(Power Line Communication·전력선통신)
IPTV 스트리밍 장비

구축내용
웹을 이용한 센서값 및 현장 영상 보기
구글맵 연동
IPTV 송출시스템 제어

:

<자료>고속도로 무선랜시범구축 (무선메쉬도입사례)-현대HDS 스트릭스
<자료>현대HDS 스트릭스(Strix) 무선메쉬
<기사>도로공사, 12월초 교통정보수집용 무선랜 구축 돌입(07.11.30)-30km구간에 1km마다 AP설치

판교IC~오산IC 30km

차량전송 -> 도로공사 본사 -> 차량뷰어
테스트 화면..



UMPC를 이용한 첫 전송 테스트




도로공사 라디오 테스트(스트리밍)
오른쪽 화면

테스트 장비
Strix 무선메쉬( OWS)
BBHCM581(파나소닉 IP카메라)

SNP-3300(삼성테크윈 IP카메라)

PDA(애니콜 블랙잭)

GPS


구축내용
무선메쉬를 이용한 IPCamera 영상전송 및 제어(PTZ)
웹뷰어(ActiveX)
PDA 뷰어
차량내 전력시스템 제어
GPS연동
TTS

:

Visual Studio ATL 보안 업데이트

Microsoft Visual Studio 2008 서비스 팩 1 보안 업데이트에 대한 설명: 2009년 7월 28일

Active Template Library Security Update for Developers

2009년 7월 30일 MS 긴급 보안공지 - 찌롱님 정리

M$가 Visual Studio 2003~2008을 위한 ATL관련 보안 업데이트를 발표했다. 아래 링크와 해당 버젼이 다를경우는 아래 관련 링크에서 원하는 툴의 버젼을 찾을 수 있다.(서비스팩에 따른 버젼 제공)
Visual Studio 2008 Service Pack 1 ATL Security Update

위 업데이트를 설치하면 VC가 사용하는 CRT,MFC,ATL등의 DLL버젼이 달라진다.
재배포 패키지(Redistributable Package)
Microsoft Visual C++ 2008 Service Pack 1 Redistributable Package ATL Security Update

설치가 잘 안될경우 아래 링크를 참조하자.
Hotfix KB 971092 for Visual Studio 2008 SP1 install problems

설치후 컴파일 에러가 날경우
Visual Studio 2008의 ATL 보안업데이트 이후 발생하는 컴파일 에러 문제

2005부터는 재배포패키지라는 개념이 도입되어 배포방법이 까다로워(?) 졌다. 서비스팩이 업데이트 될경우 재배포 패키지 또한 변경해줘야한다. 사용자 입장에선 이게 좀 불편한편인데.. 물론 대상 컴퓨터가 x86의 일반적인 CPU를 사용하는 환경이라면 재배포 패키지에서 사용하는 DLL만 가져온후 같이 배포하면 이문제가 거의 대부분 해결되기는 한다.

하지만 이번에 업데이트된 프로그램 배포시는 재배포 패키지가 항상 필요할 듯 하다. 아래 내용참고.

재배포 패키지의 DLL 버젼(VS 2008 기준)

9.0.21022.8 - 2008 기본 버젼

9.0.30729.1 - sp1

9.0.30729.4148 - sp1에 ATL관련 보안 업데이트시


Manifest에 명시되는 사용 DLL버젼
- crt와 mfc 기본만 사용할 경우.

기존 sp1 프로그램
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="requireAdministrator" uiAccess="false"></requestedExecutionLevel>
      </requestedPrivileges>
    </security>
  </trustInfo>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.30729.1" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
    </dependentAssembly>
  </dependency>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.VC90.MFC" version="9.0.30729.1" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
    </dependentAssembly>
9.0.30729.1 버젼의 crt와 mfc라이브러만 명시되어 있음.

sp1에 ATL 보안 업데이트시
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="requireAdministrator" uiAccess="false"></requestedExecutionLevel>
      </requestedPrivileges>
    </security>
  </trustInfo>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.30729.4148" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
    </dependentAssembly>
  </dependency>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.VC90.MFC" version="9.0.30729.4148" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
    </dependentAssembly>
  </dependency>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.30729.1" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
    </dependentAssembly>
  </dependency>
9.0.30729.1과 9.0.30729.4148 CRT를 둘다 필요로 한다. 버젼은 달라도 CRT의 이름은 다르므로 DLL만 포함하면 실행이 안된다. 그러므로 일반적으로 dll을 포함하던 방법으론 프로그램이 제대로 실행되지 않을 것이다.

배포할 일에 많은 개발자가 아무생각없이 자동 업데이트 했다가는 사무실이 뒤집어 질꺼다;(필자의 경험담? ㅡ.ㅡa)

ATL 보안업데이트 삭제

위와 같이 바뀌어도 인스톨쉴드에 파일 하나만 바꾸면 되는거 아니나는 분들에겐 할말 없지만 조금이라도 불편해서 삭제하고 싶은 분들은 참고하기 바란다.(아래는 필자의 경험담이며 공식문서 확인시 변경될수 있다)

위 보안 업데이트를 삭제하는 방법은 공식 문서에는 프로그램 추가/삭제에서 제거 해주면 된다고 명시되어 있다. 하지만 재배포 패키지 관련 업데이트만 목록에 존재하며 삭제를 해도 VS와는 전혀 상관없다. 윈도우 복원을 날짜를 되돌려도 설정은 바뀌지 않는다. 그래서 필자가 택한 방법은 VS를 전체 삭제하고 재설치 하는거였다 ㅡ.ㅡ; 전체삭제하고 재설치를 해도 기본 설정값들은 전부 남아있어서 크게 불편한점은 없었고 안전하게(?) 이전 버젼의 DLL을 사용한다.

위방법 적용후 필자의 결론은 추가/제거에서 관련 업데이트를 삭제후 기존에 사용하던 서비스팩만 재설치해도 문제가 해결될꺼같다는 거다.


인스톨에 대한 거부감과 DLL업데이트후 재배포 패키지를 설치해야된다는 말에 지대로 거부감 날려주신 클라이언트로 인해 이번업데이트에 대해 정리해본다. 사실 별 내용은 아닌데 결론은 개발자용 PC에 아무리 중요한 업데이트라도 아무생각없이 막 설치해서는 안된다는거다.(응?)

원본 글
http://www.devpia.com/MAEUL/Contents/Detail.aspx?BoardID=51&MAEULNO=20&no=8351&page=1

:

GDI+ (& CImage)

프로그래밍/영상, 음성 | 2009. 7. 23. 10:24 | Posted by 99%
http://www.winapi.co.kr/project/library/gdiplus/gdiplus.htm
아래내용은 김상형님의 WinApi사이트 내용을 정리한것이다. GDI+는 다른 책도 봤지만 김상형님 강좌만한게 없다.
GpExam2008.zip(4.8MB)



GDI+ 소개

 GDIPlus는 닷넷의 그래픽 출력 엔진이다. 20년전에 C함수들로 설계된 GDI와는 다르게 C++클래스로 설계되었으며 XP이후에는 기본 출력엔진 역활을 한다. DLL파일 하나로 구성되어 있으며 C++컴파일러에서도 사용할 수 있어 C++사용자들은 GDI만으론 부족했던 부분을 GDI+를 사용으로 해결할 수 있게 되었다. (VC6사용자는 플랫폼 SDK설치를 하면 사용가능)
C#에서는 GDI+기본 클래스의 내용에 몇가지를 더하고 C#의 특성을 살려 C++보다는 좀더 편하게 사용할 수 있지만 다양한 그래픽 포맷으로 인해 외부 라이브러리를 찾아쓰던 VC사용자들에겐 적극 추천할 만한 라이브러리이다.

참고로 C#의 구조를 GTK#으로 구현하여 오픈소스화고 있는 Mono프로젝트에서의 그래픽 엔진은 윈도우에선 GDIPlus를 사용하고 Linux등에선 자체 GDIPlus같은 엔진을 만들어 사용하고 있다. C#을 사용해 보신분이라면 Mono를 사용해 한번쯤 리눅스 프로그래밍을 해보는것도 좋은 경험이라 생각한다. 참고 Mono의 System.Drawing.

GDI+ - MSDN

GDI+ 사용하기

VC에서 사용하기 위해선 GDIPlus초기화 과정이 필요하다. 아래 소스로 헤더파일 선언과 GDI+초기화 과정을 간단하게 정리했으며 CGdiPlusStarter g_gps;를 위치와 상관없이 전역변수로 선언해놓으면 초기화와 해제과정을 자동으로 처리해준다. 배포시는 gdiplus.dll을 같은 폴더에 포함하기만 하면 95/98에서도 문제없이 사용할 수 있다.
#include <gdiplus.h>
using namespace Gdiplus;
#pragma comment(lib, "gdiplus")

class CGdiPlusStarter
{
private:
     ULONG_PTR m_gpToken;
public:
     bool m_bSuccess;
     CGdiPlusStarter() {
          GdiplusStartupInput gpsi;
          m_bSuccess=(GdiplusStartup(&m_gpToken,&gpsi,NULL) == Ok);
     }

     ~CGdiPlusStarter() {
          GdiplusShutdown(m_gpToken);
     }
};

CGdiPlusStarter g_gps;

참고사이트

CodeProject GDI+
-> General Graphics 섹션에도 GDI+사용 예제가 많다.

In Memory Image Compression

초보자를 위한 GDI+이미지 변환, DLL에서 클래스 익스포트 예제/라이브러리
-> GDI+이미지 변환 및 wstring & string 변환, dll과 static라이브러리를 같은 소스로 만드는 방법, 스마트 포인터와 관련된 VC++의 COM Support 등의 내용을 담고 있는 예제.

GDI+ 속도

.Net이 속도로 인해 GDIPlus라는 C++클래스 라이브러리를 만들었지만 GDI와 비교하면 확실히 속도는 떨어진다. 하지만 GDI+의 이미지 처리 클래스라던가 반투명 출력등의 기능은 GDI에는 없는 기능이고 이미지 출력같은 경우는 속도차이가 많이 나지 않는다. 그러므로 출력 품질을 위해서라도 GDI와의 연동하는 법을 배워 필요한곳에 적절히 사용하도록 하자.
아래에 GDI와 MFC, GDI+의 그래픽 처리 예제를 첨부했으며 예제를 실행해보면 시스템에따라 5~10배정도의 차이가 나고 출력부분을 반투명 처리할 경우는 700배정도의 차이가 난다.(위설명은 winapi사이트에 있는 그대로인데 필자의 시스템에선 GDI와 GDI의 차이가 2배 밖에 나지 않았다.)

GDI+ 요점

GDI+는 유니코드를 사용한다.

Status 열거형 (2. 나 참고)

GDI+의 모든 함수들은 Status 열거형으로 실행 결과를 리턴한다. 생성자로 로딩하는 Image 클래스의 에러 코드는 최후의 실패한 에러 코드를 리턴하는 GetLastStatus 함수를 사용하자. GdiPlusEnums.h 참고.

Rect
(2. 다 참고)
GDI의 RECT 구조체는 LTRB 형식으로 좌상단, 우하단 좌표로 영역을 지정하지만 GDI+ Rect 클래스는 X, Y 좌상단 좌표와 폭, 높이인 Width, Height를 멤버로 가진다. 그래서 똑같은 (10,20)-(150,100)의 영역을 표현하는 방식이 다르다.



Color (3. 가 참고)
GDI+는 색상을 Color 클래스로 표현한다. Color 클래스는 32비트의 정수로 색상을 관리하는데 8비트씩 잘라 A,R,G,B 요소를 표현한다. R,G,B는 각각 빨간색, 초록색, 파란색의 강도를 지정하며 A는 불투명도인 알파를 지정한다. 알파가 0이면 완전히 투명해서 보이지 않는 상태이며 255이면 불투명한 상태이다.

표준색상 - Color.Blue는 C#의 프로퍼티

Color Blue(0,0,255);
Pen P(Blue);
G.DrawEllipse(&P,10,10,100,100);

위 코드를 줄이면

G.DrawEllipse(&Pen(Color(0,0,255)),10,10,100,100);

처럼 만들수 있으나 C#으론

G.DrawEllipse(Pens.Blue,10,10,100,100);

이렇게 끝낼 수 있다. C#의 문법을 이용해서 몇가지 편리한 클래스가 제공되는데 아쉽게도 C++에서 따라하기엔 저렇게 간결한 문장을 만들긴 어려운 편이다.

이상이 Winapi사이트 '3.나' 까지의 정리이다.




CImage

VC.Net 툴이상(VC 7.0)을 사용하면 "atlimage.h"안에 CImage라는 기본클래스가 존재하며 여러가지 기본포맷을 CBitmap으로 간단하게 가져올 수 있다. 이 클래스는 GDIPlus를 Wrapping한 클래스이며 클래스안에 CInitGDIPlus라는 GDIPlus초기화 클래스로 CImage의 Load함수만 호출하면 내부에서 CGdiPlusStarter 클래스와 같은 일을 자동으로 처리해준다.

CImage(MSDN)

사용예제(MSDN)

사실 위 예제도 필요없으며 아래 처럼 7.0이상이면 헤더파일 선언만으로 간단히 사용가능하며 배포시에도 gdiplus만 사용할때와 같다.
#include "atlimage.h"

// Load
CImage imgae;
imgae.Load(_T("C:\\1.jpg"));

// Draw
CClientDC dc(this);
imgae.Draw(dc,0,0,100,100);

// CBitmap으로 가져오기
CBitmap* pBitmap = CBitmap::FromHandle(image.Detach());
Image클래스처럼 유니코드를 사용할 필요도 없으며 간단히 사용가능 하지만 하나를 배우면 주의사항 또한 늘어나는 법이다.

이전 운영 체제에서 CImage 제한(MSDN)
http://msdn.microsoft.com/ko-kr/library/cc468120(VS.71).aspx

'프로그래밍 > 영상, 음성' 카테고리의 다른 글

OpenCV(ComputerVision) 기본편  (1) 2009.08.19
CxImage  (0) 2009.08.19
영상처리 관련 조언, 책들...  (0) 2009.07.20
IJL(Intel Jpeg Library)  (1) 2009.04.16
:

2008년 2월 23일에 진행했던 세미나 [2008년, Visual C++와 MFC의 변화 따라잡기] 동영상..


Session 1 VC++ 2008 업데이트, MFC 업데이트

(김광태 선임 연구원 / 안철수 연구소)

 

2008, MFC가 대폭 업데이트 되었습니다. 거의 두 배로 커진 MFC에 어떤 새로운 기능이 포함되었으며 어떻게 사용해야 하는지 일선 개발자의 입장에서 알아 봅니다.

 

http://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032372500&EventCategory=3&culture=ko-KR&CountryCode=KR




Session 2Visual C++ 2008을 이용한 debugging Crash Dump Analysis 노하우 2008

(신경준 MVP / 안철수 연구소)

 

많은 개발자들이 User Mode Code를 작성하고 있습니다. 그러나 실제 개발 단계와 유지 보수 단계에서 debugging에 어려움을 겪는 경우가 많습니다. Visual C++ 2008를 이용하여 이러한 어려움을 극복하기 위한 debugging & crash dump analysis 노하우를 알아봅시다

http://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032372501&EventCategory=3&culture=ko-KR&CountryCode=KR



: