참고 소스 : DirectX SDK – DirectX 11 Tutorial 01

위 소스를 기반으로 연재를 진행합니다.

연재외에 자세한 내용은 소스와 DX SDK 문서를 참조하시면 도움이 됩니다.

 

안녕하세요. 알콜코더 민군입니다. ^^

그동안 연재를 본의 아니게 많이 쉬었습니다. 거의 두달만에 다시 연재를 재개하는 것 같네요..OTL

회사 프로젝트가 바쁜데다가 여러 가지 발표와 행사가 겹쳐서 너무 오래 연재를 쉰 것 같네요. 그럴리는 없겠지만… 혹시나 이런 허접한 연재를 기다리신 분들에게는 죄송합니다. T^T 앞으로는 더욱 열심히 자주 업데이트 하도록 하겠습니다. ^^;;

이번 연재에서는 저번 연재 마지막에 언급했던 DX11 디바이스와 스왑 체인을 생성하는 방법에 대해서, 좀더 자세히 알아볼까 합니다. DX를 이용한 모든 프로그램에서는 DX 디바이스를 생성하는 것이 가장 기본이 됩니다. 그전까지의 과정들은 전부 디바이스를 생성하기 위한 준비단계에 해당합니다. 그리고 DX10 버전부터는 DXGI 기반 구조로 변경되면서 스왑체인(SwapChain)과 디바이스 컨텍스트를 생성해야 합니다. 스왑체인에 대한 설명은 이전 연재를 참조하시면 됩니다.

 

 

디바이스와 스왑체인의 생성

 

디바이스와 스왑체인은 'D3D11CreateDeviceAndSwapChain' 함수를 이용해서 동시에 생성합니다.

이때 실제 렌더링에 사용하는 백버퍼인 Device Context 역시 함께 생성됩니다.


 

함수는 위와 같은 형태로 사용됩니다. 들어가는 인자들이 꽤 많죠. ^^

DX11의 가장 기본이자 핵심인 함수이기 때문에 세팅을 해야하는 내용들이 꽤 많습니다.

이제부터 하나하나 들어갈 인자들을 설명해 드리겠습니다.

여기에 들어가는 인자들을 만드는 방법은 이전 연재를 참고하시면 됩니다.

 

함수 원형 및 인자들에 대한 설명은 아래와 같습니다.


HRESULT D3D11CreateDeviceAndSwapChain(

__in   IDXGIAdapter               *pAdapter,

__in   D3D_DRIVER_TYPE      DriverType,

__in   HMODULE                     Software,

__in   UINT                                Flags,

__in   const D3D_FEATURE_LEVEL *pFeatureLevels,

__in   UINT                               FeatureLevels,

__in   UINT                               SDKVersion,

__in   const DXGI_SWAP_CHAIN_DESC *pSwapChainDesc,

__out  IDXGISwapChain        **ppSwapChain,

__out  ID3D11Device             **ppDevice,

__out  D3D_FEATURE_LEVEL *pFeatureLevel,

__out  ID3D11DeviceContext **ppImmediateContext

);

pAdapter 

표시할 '디스플레이 디바이스(비디오 카드)'의 'IDXGIAdapter 인터페이스'를 설정합니다. 이것은 DXGI의 인터페이스입니다. NULL을 지정하면 최초에 발견한 디바이스를 사용합니다. 비디오카드를 지정할 필요가 있을때를 제외하고는 기본적으로 NULL로 설정하면 됩니다

DriverType 

생성할 DX11 디바이스의 종류를 지정합니다. 보통은 하드웨어 가속을 사용하기 위해서 'D3D_DRIVER_TYPE_HARDWARE'를 지정합니다. pAdapter에 NULL 이외의 값을 지정한 경우에는'D3D_DRIVER_TYPE_UNKNOWN'을 지정합니다.

Software 

소프트웨어 래스터라이저가 구현되어 있는 DLL이 핸들을 지정합니다.보통은 NULL을 설정하면 됩니다.

Flags 

사용할 DX11의 API 레이어를 D3D_CREATE_DEVICE_FLAG 값들을 조합하여 설정합니다.

pFeatureLevels

피처레벨(지원 기능 레벨) 배열을 설정합니다. 우선 순위가 높은 순서대로 배열을 채웁니다. 만약 NULL로 설정하면 DX11->DX10->DX9 순으로 모든 레벨을 설정합니다.

FeatureLevels 

위에서 설정한 피처레벨 배열의 개수를 입력합니다

SDKVersion

사용하고 있는 DX SDK의 버전을 넘겨줍니다.

pSwapChainDesc 

스왑체인의 설정값들을 저장한 구조체의 포인터를 넘겨줍니다.

ppSwapChain 

생성된 스왑체인 인터페이스의 포인터를 담을 변수를 설정합니다.

ppDevice 

생성된 디바이스 인터페이스의 포인터를 담을 변수를 설정합니다.

pFeatureLevel 

생성에 성공한 경우에는 pFeatureLevels에서 지정했던 배열의 처음값을 돌려줍니다. 실패한 경우에는 0이 반환됩니다.

ppImmediateContext 

생성된 디바이스 컨텍스트 인터페이스의 포인터를 담을 변수를 설정합니다.

 

D3D_DRIVER_TYPE

D3D_DRIVER_TYPE_HARDWARE

하드웨어 드라이버 (HAL 드라이버)

D3D_DRIVER_TYPE_REFERENCE 

레퍼런스 레스터라이저 (REF 드라이버)

D3D_DRIVER_TYPE_NULL 

NULL 디바이스, 렌더링이 불가능한 레퍼런스 드라이버

D3D_DRIVER_TYPE_SOFTWARE 

예약만 되어있음. 사용하지 않습니다.

D3D_DRIVER_TYPE_WARP 

고속 퍼포먼스의 소프트웨어 레스터라이저(WARP). 피처레벨 9_1 ~ 10_1을 지원합니다.

D3D_DRIVER_TYPE_UNKNOWN 

종류 불명

 

D3D11_CREATE_DEVICE_FLAG

D3D11_CREATE_DEVICE_SINGLETHREADED

싱글 스레드 지원의 디바이스를 지정. 억지로 스레드 세이프 레이어를 무효로 하고 싶은 경우에 지정합니다.

D3D11_CREATE_DEVICE_DEBUG

디버그 레이어를 사용합니다.

D3D11_CREATE_DEVICE_SWITCH_TO_REF

레퍼런스 타입으로 교체할 수 있는 레이어를 사용합니다.

D3D11_CREATE_DEVICE_PREVENT_

INTERNAL_THREADING_OPTIMIZATIONS

복수의 스레드가 만들어지지 않도록 한다. 일반적으로는 사용되지 않습니다.

D3D11_CREATE_DEVICE_BGRA_SUPPORT

Direct2D 와 Direct3D 리소스의 상호운영을 가능하게 합니다.

 

 

디버그용 디바이스

 

'D3D11CreateDeviceAndSwapChain' 함수의 3번째 인자에는 D3D_CREATE_DEVICE_FLAG 의 조합이 들어가게 됩니다. 이 조합된 플래그값으로 게임에서 사용할 Direct3D11의 API 레이어를 지정할 수 있습니다. 여기서 디버그용 디바이스 플래그도 설정이 가능합니다. 아래와 같이 디버그용 버전에서는 디버그 레이어를 켜두면 여러가지 디버그 정보들을 확인할 수 있습니다.


위와 같이 설정하고 D3D11CreateDeviceAndSwapChain 함수의 3번째 인자에 위 플래그를 설정해주면, 디버그 버전으로 컴파일 되는 경우에만 디버그 레이어를 사용할 수 있습니다. 디버그 레이어를 사용 가능하게 해두면 프로그램의 성능이 떨어지기 때문에, 릴리즈에서는 사용하면 안됩니다.

 

 

WARP 디바이스의 생성

 

DX11에서는 하드웨어 드라이버가 사용할 수 없는 환경에서도, 높은 퍼포먼스의 소프트웨어 레스터라이저인 WARP(D3D_DRIVER_TYPE_WARP) 디바이스를 사용할 수 있습니다. 이전 DX 버전에서는 하드웨어가 지원되지 않는 경우 100% 소프트웨어 레스터라이저인 레퍼런스 디바이스를 사용해야 했는데, DX11과 윈도우 비스타 이상에서는 윈도우의 기본적인 아키텍쳐가 하드웨어 가속이 지원 되기 때문에 이 WARP 디바이스를 사용하면 훨씬 더 고속의 렌더링을 할 수 있습니다. 즉, 프로그램이 실행되는 환경의 그래픽 카드가 피처레벨이 지원되지 않는 그래픽카드라고 할지라도, DX11 SDK로 WARP 디바이스를 생성하면 DX11 프로그램을 동작시킬 수 있습니다. 하지만 WARP 디바이스가 지원하는 피처레벨은 'D3D_FEATURE_LEVEL_9_1' ~ 'D3D_FEATURE_LEVEL_10_1' 까지입니다.

WARP 디바이스는 윈도우 비스타이상에서만 사용 가능합니다.


 

 

레퍼런스 디바이스의 생성

 

앞서 이야기한 WARP는 고속이긴 하지만, DX10 버전의 기능들까지만 지원하기 때문에 DX11의 기능들은 사용할 수가 없습니다. 하지만 프로그램을 개발할 때 DX11 지원 그래픽카드가 없는 환경에서, DX11의 모든 기능을 테스트 해보기 위해서는 DX11의 모든 기능들이 구현되어 있는 레퍼런스 디바이스를 사용해야 합니다. 주의할 점은 레퍼런스 드라이버는 'DirectX SDK'가 인스톨되어있는 환경에서만 사용 가능합니다.

튜터리얼의 소스 코드에서는 DX11을 지원하지 않는 그래픽카드를 위해서 '하드웨어 디바이스 -> WARP 디바이스 -> 레퍼런스 디바이스' 순으로 생성을 해보는 코드가 포함되어 있습니다. 그래서 만약 성공했다면 그 디바이스를 사용하고, 만약 앞의 단계에서 생성에 실패했다면 다음 단계의 디바이스를 생성해 보게 됩니다. 그래서 DX11을 지원하지 않는 그래픽 카드를 가지고 있어도 샘플 코드의 실행이 가능합니다. 만약 윈도우 비스타 이하 버전에 DX11을 지원하지 않는 그래픽카드를 사용하고 있다면, WARP를 사용할 수 없기 때문에 레퍼런스 디바이스가 생성됩니다. (물론 DX11 지원 그래픽 카드라면 당근 하드웨어 디바이스가 생성되겠죠)


 

 

다음 시간에는…

 

다음 연재에서는 위와 같이 방법으로 생성한 스왑체인으로 백버퍼를 가져와서, 렌더 타겟 뷰를 생성하고, 생성된 렌더타겟뷰를 디바이스 컨텍스트에 설정하는 방법을 다루겠습니다. 즉, 실제로 게임 화면을 렌더링하는 백버퍼를 생성하는 단계에 대해서 이야기 해보겠습니다. ^^

 

Ps. 조금이라도 도움이 되셨다면, 응원의 리플을~~!!! 굽신~굽신~~

 

알콜코더 민군

언젠가 우즈벡에 미소녀 게임 회사를 차리고 싶은 개발자

3D게임 클라이언트 프로그래머, 살짝 오타쿠…

드래곤볼 온라인 개발, 현재는 네오위즈 서식중

'신입게임 개발자의 서울상경기' '초중급 게임개발자 스터디' 운영중

 

[알콜코더의 미리 배워보는DX11 입문편] DirectX 11의 특징들

DirectX 11 2010. 12. 28. 22:01 Posted by 알 수 없는 사용자


안녕하세요. 알콜코더 민군입니다. ^^

그동안 연재를 한동안 못하고 있었습니다. 에궁.

회사의 게임 개발일이 바쁘다보니 그동안 시간을 제대로 못냈네요.

죄송합니다.. 앞으로 열심히 하겠습니다. T^T

 

그동안 연재가 많이 끊겨서, 그전의 내용의 복습겸해서…

이번 연재에서는 DX 11의 특징에 대해서 간략하게 정리하였습니다.

그동안 잊고 있엇던(?) 내용들을 다시 한번 새롭게 정리하는 기회가 되시길 바랍니다. ^^

 

DirectX 11의 특징    

Direct3D 11은 윈도우 비스타, 윈도우 7에서 지원되는 Direct 3D의 최신 버전입니다. 기능의 확장, 퍼포먼스의 개선, GPU 메모리의 완전한 추상화, GPGPU 지원 기능, 등 보다 유연하고 뛰어난 기능들이 심플한 API셋트로 제공됩니다.

Direct3D 11은 Direct3D 9까지의 Direct3D와는 하드웨어 레벨부터 소프트웨어 레벨까지 전부 근본적으로 변경되었습니다. Direct3D 10을 확장한 구조로 되어 있어서, Direct3D 10에서의 개발 이행이 용이합니다.

 

  • 컴퓨트 셰이더 (Compute Shader)

    OS나 일반 어플리케이션 프로그램 등을 실행하는 범용 프로세서인 CPU에 대해서, 그래픽스 처리에 특화된 전용 프로세서를 일반적으로 GPU라고 말합니다만, Direct3D 11에서 지원되는 [컴퓨트 셰이더](Compute Shader)을 사용하면, 그래픽스 처리 이외에도, 데이터를 병렬 처리하는 범용적인 프로세서로 GPU를 활용하는 것이 가능합니다.

    컴퓨트 셰이더는 Direct3D 디바이스를 통해서 그래픽스계열 셰이더와 리소스를 공유 가능합니다만, 다른 셰이더와는 직접 연결이 불가능합니다.

     

    테셀레이션(Tessellation)

    테셀레이션은 디테일이 낮은 모델을 분할하여, 보다 세밀한 프리미티브를 생성하여 출력하는 기능입니다.

    Direct3D 11의 그래픽스 파이프라인에는 테셀레이션을 수행하는 새로운 하나의 스테이지와 2개의 셰이더가 추가 되어서, 리얼타임에서 테셀레이션의 실행이 가능합니다.

     

    멀티스레드 렌더링

    Direct3D 11에서는 멀티스레드의 대응이 강화되어, Direct3D 10의 [디바이스](ID3D10Device 인터페이스)의 기능은 [디바이스](ID3D11Device 인터페이스)와 [디바이스 컨텍스트](ID3D11DeviceContext 인터페이스)로 분할 되었습니다.

    [디바이스 컨텍스트]에서는 [이미디어트 컨텍스트](Immediate Context)와 [디퍼트 컨텍스트](Deferred Context)가 있습니다.

    이미디어트 컨텍스트는 디바이스에 직접 렌더링하는 디바이스 컨텍스트이며, 디바이스에 하나가 존재합니다. 싱글 스레드의 어플리케이션은 이미디어트 컨텍스트만을 사용합니다.

    디퍼드 컨텍스트는 메인 렌더링 스레드 이외의 워커 스레드로 사용되는 디바이스 컨텍스트입니다.

    또한 [디바이스](ID3D11Device 인터페이스)의 메소드는 멀티 스레드에 안전하게 되어있지만, [디바이스 컨텍스트](ID3D11DeviceContext 인터페이스)의 메소드는 프리 스레드화 되어 있지 않습니다.

     

    동적 셰이더 링크

    일반적인 렌더링에서는 각종 마테리얼을 여러가지로 조합하면 렌더링을 하게 됩니다. 그 때문에 각각의 렌더링마다 서로 다른 셰이더가 필요하게 됩니다.

    이러한 셰이더를 작성하는 방법으로는 "(1)모든 기능을 포함하고 있는 셰이더를 만드는 방법" 과 "(2) 필요한 조합합의 셰이더만을 만든느 방법"이 있습니다만, (1)의 방법에서는 셰이더의 퍼포먼스가 희생이 되고, (2)의 방법에서는 셰이더의 조합이 조금씩 늘어나는 것만으로 상당히 많은 양의 세이더를 처리할 필요가 생깁니다.

    Direct3D 11에 도입된 '동적 셰이더 링크'를 사용하면, 셰이더를 파이프라인에 분할 할당하여, 셰이더 코드를 드라이버에서 최적화가 가능하게 되었습니다.

     

    WARP(Windows Advanced Rasterizer Platform)

    WARP는 실제 어플리케이션에서 이용 가능한, 고속의 '멀티 코어 스케일링 래스터라이저'입니다. Direct3D 10.1 레벨의 기능을 지원하는 어플리케이션에서, 지원 가능한 하드웨어를 찾지 못하는 경우에 WARP 디바이스를 선택합니다.

    비슷한 기능으로, Direct3D의 모든 기능을 소프트웨에서 구현했던 '레퍼런스 레스터라이저'가 있습니다만, 이 것은 실행 속도가 상당히 느리고, 개발용으로 밖에 사용할 수 밖에 없다는 한계가 있습니다.

     

    Direct3D 9/10/10.1 레벨의 하드웨어를 지원

    Direct3D 10을 사용한 프로그램을 실행하기 위해서는 Direct3D 10을 지원하는 그래픽스 하드웨어가 필요했었습니다. 그러나 Direct3D 11에서는 6단계의 '기능 레벨'(Feature Level)을 정의하여서, Direct3D 9/10/10.1의 디바이스에서도 대응하는 '기능 레벨'에 맞게 DirectX 11의 기능을 사용한 프로그램이 실행 가능합니다.

     

    세이더 모델 5.0 (Shader Model 5.0)

    Direct3D 11에서는 Direct3D 10과 동일하게 '통합형 셰이더(Unified Shader) 아키텍쳐'가 채용되었기 대문에, '컴퓨트 셰이더'를 포함한 모든 셰이더를 하나의 HLSL(High Level Language : 고수준 셰이딩 언어)에 작성 가능합니다.

    Direct3D 11의 셰이더 모델은 '셰이더 모델 5.0(SM5.0)'입니다. 또한 셰이더 모델 4.0의 기능도 확장되었습니다.

     

    리소스

    Direct3D 11에서는 '읽고/쓰기 버퍼 (텍스쳐)', '구조화 버퍼', '바이트 어드레스 버퍼', 'Unodered Access Buffer(텍스쳐)'등의 새로운 리소스 타입이 정의되었습니다.

    또한 4GB보다 큰 리소스를 지원하게 되었습니다. (다만, 리소스 인덱스는 32bit 입니다)

     

    Direct3D 10의 특징을 승계

    Direct3D 11은 Direct3D 10을 확장한 설계 형태로 되어 있습니다. 그래서 Direct3D 10의 '디바이스의 소멸 처리가 필요없음', 'CAPS 비트의 폐지', '고정 기능의 폐지', '지오메트리 셰이더'등의 특징을 물려받았습니다.

     

     

    Ps. 다음 시간부터는 그동안 중지되었던 DX11 튜터리얼 연재와 함께 DX11의 기본 개념들에 대한 연재도 같이 진행하겠습니다.

    Ps2. 그동안 연재가 너무 많이 쉬었습니다. 흑.. OTL 다음 연재부터는 빨리 빨리 올리도록 하겠습니다. ^^



                                                                                                                                                             

    언젠가 우즈벡에 게임 회사를 차리고 싶은 오타쿠 개발자

    3D게임 클라이언트 프로그래머

    드래곤볼 온라인 개발, 현재 네오위즈 서식중

    '신입게임 개발자의 서울상경기'와 '초중급 게임개발자 스터디' 운영중


[Step. 20] 닷넷에서 HalfNetwork를 사용하자 - 1

C++/CLI 2010. 12. 27. 09:00 Posted by 알 수 없는 사용자

C++/CLI를 가장 자주 사용하는 경우가 아마 C++로 만든 코드를 닷넷에서 사용하고 싶을 때라고 생각합니다. 게임 개발에서는 보통 3D 툴을 만들 때 C++/CLI를 유용하게 사용합니다.

 

C++/CLI를 툴 개발에서 사용할 때는 보통 두 가지로 사용하는데 첫 번째는 C++로 만든 3D 엔진 코어를 DLL로 만들어서 C#을 이용하여 툴을 만들던가, 두 번째는 C++/CLI에서 관리코드와 비관리코드를 같이 사용할 때입니다.

 

제가 앞서 C++/CLI에 대해서 설명한 것들은 C++/CLI로만 프로그래밍 하는 것보다는 관리코드와 비관리코드를 같이 사용할 때를 생각하여 이때 필요로 하는 부분을 중심으로 했습니다. 그래서 아직 C++/CLI에 대한 많은 부분들이 빠져있습니다. 빠진 부분에 관심이 있는 분들은 C++/CLI 책이나 MSDN을 통해서 공부하시기 바랍니다.

 

앞으로 C++로 만든 코드를 C++/CLI를 사용하여 닷넷용 클래스 라이브러리를 만든 후 이것을 C#에서 사용하여 프로그램을 만든다는 경우로 간단한 프로그램을 만들면서 C++/CLI을 어떻게 사용하는지 몇 회에 걸쳐서 설명하겠습니다.

 

만들 프로그램은 네트웍 서버 애플리케이션입니다(제가 회사에서 맡은 직무가 온라인 게임 서버 개발입니다). ^^

 

 

네트웍 라이브러리(또는 프레임웍)

네트웍 프로그래밍은 일반적인 프로그래밍은 아니고 시스템 프로그래밍입니다. 조금은 특수한 분야라고 할 수 있습니다.

그러나 한국의 게임업계는 거의 대부분이 온라인 게임이라서 네트웍 프로그래밍이라는 것이 특수한 부분은 아닙니다.

 

보통 게임 프로그래밍이라는 것은 그래픽스 프로그래밍을 쉽게 떠올리고, 시중에 관련 책이나 학원들이 있습니다. 그러나 네트웍 프로그래밍에 관한 책이나 학원은 별로 없습니다(특히 전문 학원은 없는 것으로 알고 있습니다).

온라인 게임에서의 네트웍 프로그래밍을 한다라는 것은 대용량 네트웍 프로그램을 만들어야 한다는 것입니다. 그래서 온라인 게임 서버 프로그램을 만들려면 시스템 프로그래밍에 관한 지식과 네트웍 프로그래밍에 대한 경험이 필요합니다.

이런 이유 때문에 서버 프로그램을 만든다는 것은 쉽지 않습니다. 그러나 서버 프로그램을 쉽게 만들 수 있도록 도와주는 라이브러리를 사용할 수 있다면 어려움은 한층 작아질 것입니다.

 


온라인 게임 강국답게 한국에는 유료,무료의 네트웍 라이브러리가 있습니다.


유료용으로는 프라우드넷( http://nettention.co.kr/kr/ )이라는 것이 있습니다.

다양한 프로젝트에서 사용되어 높은 신뢰성과 편리하고특다양한 기능을 가지고 있으며 특히 P2P에서 아주 강합니다.


( 프라우드넷을 사용한 유명한 게임으로는 넥슨의 마비노기 영웅전이 있습니다)


그리고 무료용으로는 HalfNetwork( http://code.google.com/p/halfnetwork/ )OCF( http://ocf.kr/ ) 등이 있습니다. 둘 다 실제 게임 개발에서 사용하고 있는 것으로 신뢰도가 높다고 할 수 있습니다.





이 중 HalfNetwork의 개발에는 저도 아주 조금이나마 참여를 하고 있어서 HalfNetwork를 사용하여 C#으로 간단한 서버 프로그램(아주 간단한 네트웍 기능만 가지고 있는)을 만들어 보겠습니다.

 

그럼 HalfNetwork에 대한 설명은 다음 회에 하겠습니다.

 

테스트 가상화...

몇 해 전부터 클라우드(Cloud) 붐이 일어나면서 굉장히 다양한 클라우드 인프라와 서비스가 여러 벤더에 의해 발전해 왔습니다. 그 중 Microsoft 는 가상화 기술을 기반으로 플랫폼, 인프라 서비스 등이 결합하여 Azure 라는 훌륭한 클라우드 서비스 환경을 구축하였습니다. 이런 클라우드 서비스의 가능성은 가장 최하위 기반이 되는 가상화 기술이 바로 그것입니다.

필자는 처음에는 클라우드라는 것이 도대체 GREEN IT 를 마케팅 용어로 벗삼고, TOC 절감과 관리적인 요소들에 그저 불편한 심기를 내비쳤습니다. 왜냐하면 늘 그래왔듯이 거품이 빠지고, 걸음마 수준의 기술과 마케팅으로 수 많은 것들이 기억 속에서 사라진 것들이 더 많기 때문입니다.

다시 본론으로 돌아와서, 테스트 가상화란…? 가상화 기술은 여러 가지 기술이나 트랜드와 접목시킬 수 있습니다. 그 중 하나가 바로 테스트 가상화 기술입니다. 현대의 소프트웨어는 다양한 방면에서 애자일(Agility) 하길 원합니다. 개발 팀은 당연하고 소프트웨어를 사용하는 사용자도 매우 능동적이며 한층 눈높이가 높아졌습니다. 즉, 기존의 개발 방식이 변하듯이 기존의 테스트 방식도 이제 진화해야 할 시기입니다. 그리고 이것을 가능하게 해 주는 것이 바로 테스트 가상화 입니다.

------------------------------------- 절취선 ^^ ------------------------------------

서두는 이쯤 마무리 하고(^^), 아래의 자료는 Microsoft 고객사를 대상으로 하는 Visual Studio Ultimate 맴버쉽 세미나에서 발표할 예정이었던 프레젠테이션 자료입니다. 2010년 12월 22일 예정이었던 세미나를 위해 급하게 만들었던 프레젠테이션인데 일정이 변경되면서 먼저 공유해 드리겠습니다. (나중에 더 알차게 만들어 드리겠습니다 ^___^;)

그림만 있어서 내용은 이해하는데 충분히 설명을 드릴 수 없습니다만, 다음 기회에 더 좋은 내용으로 정보를 공유하도록 하겠습니다.

   


[Step. 19] char* -> 관리코드, 관리코드 -> char*

C++/CLI 2010. 12. 20. 09:00 Posted by 알 수 없는 사용자

char*는 문자열을 뜻하는 것이 아니고 char형의 포인터를 뜻합니다.

C++의 네트웍 프로그래밍에서는 네트웍으로 데이터를 주고 받을 때 char* 타입으로 주고 받습니다.

 

// 보내기

char* pPacket;

Send(pPacket, nLength);


// 받기

char* pBuffer = new char[MAX_BUFFER];

int nLength = Receive( pBuffer );

 

C++/CLI에서 C++로 만든 네트웍 라이브러리를 사용하는 경우 필연적으로 char*을 관리코드로 바꾸고, 관리코드를 char*로 바꾸어야 하는 경우가 있을 것입니다.



 

char* -> 관리코드


C++/CLI에서 char* array< Byte >로 마샬링 하면 됩니다.

// 비관리코드

int nPacketSize = 34;

char* pPacket = new char[34];

 

// 관리코드

array< Byte >^ byteArray = gcnew array< Byte >(nPacketSize);

System::Runtime::InteropServices::Marshal::Copy( (IntPtr)pPacket, byteArray,

0, nPacketSize );

 

 

관리코드 -> char*

 

// 관리코드

array<Byte>^ SendData;

….

 

// 비관리코드

int nLength = SendData->Length;

pin_ptr<Byte> pData = &SendData[0];

                    

char* pBuffer = new char[ nLength ];

CopyMemory( pBuffer, pData, nLength );

 

참고로 C++/CLI에서는 바이트형 배열 array<Byte> C#에서는 byte[] 이 됩니다.

 

[Step. 18] 순수 가상 함수

C++/CLI 2010. 12. 10. 17:53 Posted by 알 수 없는 사용자

C++에서는 순수 가상 함수를 선언할 때는 아래와 같이 합니다.

class Server

{

  .....

  virtual void OnAccept() = 0;

};

 

그러나 C++/CLI에서는 abstract라는 키워드를 사용합니다.

그래서 위의 코드는 아래처럼 바꾸어야 합니다.

public ref class Server

{

   .....

   virtual void OnAccept() abstract;

};

 

그런데 이렇게만 하면 클래스는 abstract가 아니라는 경고가 나옵니다.

경고를 없애고 싶다면 클래스에도 abstract를 붙여줍니다.

public ref class Server abstract

{

   .....

   virtual void OnAccept() abstract;

};

 

 

WCF Troubleshooting (2)

WCF 2010. 11. 29. 09:00 Posted by 알 수 없는 사용자
일주일 만에 돌아온 RuAA 입니다. 하핫~
이제 곧 올해의 마지막인 12월이네요~ 어느새,, 벌써,, ㅡㅠ
나이만 먹는 것 같아 참 슬퍼지려 합니다.
12월엔 술자리도 많고, 행사도 많아 바빠지는데, 모두 건강 챙기시길 바랍니다.


다른 설명 없이 바로~ 지난 포스트에 이어서, 진행해보도록 하겠습니다~

이번 포스팅에서는 FaultContractAttribute 대해서 잠깐 알아보고, 이를 이용하여 에러 메시지를 직접 정의해보도록 하겠습니다.

그럼, FaultContractAttribute 무엇이냐~? 간단하게아주 간단하게직접 정의한 에러 메시지를 클라이언트로 전달하기 위한 서비스 메서드의 속성이라고 생각하면 됩니다.

닷넷에는 기본적으로 제공하는 여러 종류의 예외 클래스가 존재합니다. 지난 포스트에서 봤듯이 이러한 예외가 발생하였을 때는 그에 맞는 예외 클래스에 정의되어 있는 메시지들이 클라이언트로 전달되었습니다
.
하지만, 이러한 메시지들 이외에
서비스 정책에 맞는 메시지를 따로 정의하고, 이를 클라이언트에 노출하고 싶을 , FaultContractAttribute 사용할 있습니다.

그럼, 이를 이용해,  특정 에러 메시지를 정의하고, 메시지를 클라이언트에 전달하는 예제를 한번 보도록 하겠습니다. 예제 한번 보고 나면 이해가 되실겁니다. 하하

우선, WCF 서비스에서 사용할 있는 새로운 클래스를 정의합니다. 물론, DataContractAttribute 이용해서요~


[
DataContract]

public class ErrorInfo

{
    [
DataMember]

    public string Info { get; set; }

 

    [DataMember]

    public ErrorCode Code { get; set; }

}

 

[DataContract]

public enum ErrorCode

{

    [EnumMember]

    WrongName,

    [EnumMember]

    NotExist

}

 


ErrorInfo 라는 이름의 클래스를 정의 하였습니다. 클래스에는 에러의 정보를 담을 있는 Info 라는 프로퍼티가 있고, 에러의 종류를 나타내는 Code 라는 프로퍼티가 정의되어 있습니다. 또한, 덤으로 에러 종류를 쉽게 분류하기 위하여 ErrorCode 라는 이름의 열거형을 정의하였습니다.

그럼, FaultContractAttribute 어디에 정의하는 걸까요? 다음 코드를 보시면 바로 있습니다~


[
ServiceContract]

public interface IService1

{

[OperationContract]

int Divide(int numerator, int denominator);

 

    [OperationContract]

    [FaultContract(typeof(ErrorInfo))]

    int FindEmployee(string employeeId);

}

 


보이시죠? ~ 바로 OperationContractAttribute 같은 위치에 선언됩니다. 예제에서 FindEmployee 오퍼레이션은 ErrorInfo 타입의 에러 메시지가 발생할 있다는 것을 나타냅니다.

이제, 직접 ErrorInfo 클래스에 에러 메시지를 정의하고, 클라이언트로 전달하는 코드를 보셔야죠~
다음 예제를 보겠습니다.


public
class Service1 : IService1

{

    public int Divide(int numerator, int denominator)

    {

        return numerator / denominator;

    }

 

    public int FindEmployee(string employeeId)

    {

        // 사용자 정의 에러 발생

        FaultReason reason = new FaultReason(string.Format("{0} employee is not exist", employeeId));

        ErrorInfo error = new ErrorInfo

        {

            Info = string.Format("Not Exist Employee, ID : {0}", employeeId),

            Code = ErrorCode.NotExist

        };

 

        throw new FaultException<ErrorInfo>(error, reason);

    }

}

 


FindEmployee 메소드는 무조건 예외를 발생하도록 되어 있습니다. 사실, 에러 메시지를 클라이언트로 전달하는 것이 목적이니깐 다른 코드는 예제에서 생략이 되어도 상관없겠죠~ ^^

FaultReason 이라는 새로운 클래스도 눈에 띄는군요~ 클래스는 해당하는 오류의 간단한 메시지를 작성하기 위한 클래스라고 생각하시면 됩니다.

그리고, 방금 만들었던 ErrorInfo 인스턴스를 생성하고, Info, Code 프로퍼티에 클라이언트로 전달하고 싶은 오류 메시지를 입력하였습니다.
마지막으로 FaultException<T> 이용하여 ErrorInfo 포함한 예외를 발생시켰습니다
.
FaultException
클래스는 SOAP 오류로 변환될 있는 예외 클래스입니다.

이제, 클라이언트에서 에러메시지를 낚아채어(?) 보여주는 예제를 보겠습니다.
콘솔 어플리케이션을 생성하고, 서비스 참조를 후에 다음과 같이 코드를 작성 해보았습니다.


static
void Main(string[] args)

{

    Service1Client proxy = new Service1Client();

 

    try

    {

        proxy.Divide(5, 0);

    }

    catch (FaultException ex)

    {

        Console.WriteLine("Reason : {0}", ex.Reason.ToString());

        Console.WriteLine("Message : {0}", ex.Message);

        Console.WriteLine();

    }

 

    try

    {

        proxy.FindEmployee("RuAA");

    }

    catch (FaultException<ErrorInfo> ex)

    {

        Console.WriteLine("Reason : {0}", ex.Reason.ToString());

        Console.WriteLine("Message : {0}", ex.Message);

        Console.WriteLine("\n<< Detail Info >>");

        Console.WriteLine("Code : {0}", ex.Detail.Code);

        Console.WriteLine("Info : {0}", ex.Detail.Info);

    }

}

 


처음엔 Divide 오퍼레이션을 호출하여 닷넷에서 기본적으로 제공하는 예외를 발생시켰고, 번째 try, catch 문에서 FindEmployee 오퍼레이션을 호출 하였습니다.

위의 코드에서 보듯이, 클라이언트에서 서비스의 예외를 낚아채기(?) 위해선 FaultException 클래스를 사용합니다. FaultException 클래스에 제네릭 형식이 정의되어 있지 않은 경우엔 닷넷에서 제공하는 기본적인 예외 메시지를 catch 있으며, 서비스에 정의 특정 예외 메시지를 catch 하고자 , FaultExcepton 클래스에 제네릭 형식을 지정해주면 됩니다.

그리고, 가지 주목할 점은, ErrorInfo 인스턴스가 FaultException 인스턴스의 Detail 프로퍼티에 입력된다는 것입니다. 이는, 뒤에 보여줄 SOAP Fault 메시지를 확인하면 아마 이해가 쉬우실겁니다.
때문에, (서비스 오퍼레이션에서 정의했던
) ErrorInfo 클래스의 Info, Code 프로퍼티에 입력된 값을 가져오기 위해선 ex.Detail.Code(또는 ex.Detail.Info) 같이 접근 하여야 합니다.

이렇게 처리를 하면, 다음과 같은 클라이언트 결과를 확인할 있습니다.


마지막으로, 서비스에서 클라이언트로 전달되는 SOAP 메시지를 확인해 보겠습니다.

 

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">

  <s:Header>

    <a:Action s:mustUnderstand="1">http://tempuri.org/IService1/FindEmployeeErrorInfoFault</a:Action>

    <a:RelatesTo>urn:uuid:c67dd581-4b6d-4a02-aa35-fba3515a0ccf</a:RelatesTo>

  </s:Header>

  <s:Body>

    <s:Fault>

      <s:Code>

        <s:Value>s:Sender</s:Value>

      </s:Code>

      <s:Reason>

        <s:Text xml:lang="en-US">RuAA employee is not exist</s:Text>

      </s:Reason>

      <s:Detail>

        <ErrorInfo xmlns="http://schemas.datacontract.org/2004/07/Wcf_TroubleShooting"

                   xmlns:i="http://www.w3.org/2001/XMLSchema-instance">

          <Code>NotExist</Code>

          <Info>Not Exist Employee, ID : RuAA</Info>

        </ErrorInfo>

      </s:Detail>

    </s:Fault>

  </s:Body>

</s:Envelope>

 


SOAP 메시지를 확인해 보면 ErrorInfo 라는 엘리먼트가 눈에 ~!! 띄는군요. 하하
이렇게 SOAP 메시지의 내용과 앞의 예제 코드, 그리고 클라이언트의 결과 화면을 비교해보면 이번 포스팅의 내용이 이해하기 쉬울 같습니다. ^^

아직 얘기가 많지만, 다음 포스팅을 기약하면서, 마무리 하도록 하겠습니다.

WCF Service Configuration Editor

WCF 2010. 11. 24. 15:19 Posted by 알 수 없는 사용자
 WCF를 사용할때 제가 여러곳에서 받는 가장 큰 피드백은 방대한 양의 설정파일입니다. 어떤 설정이 있는지 , 어떤 경우에 어떤 설정을 사용해야 하는지 곤란한 경우가 참 많을거라고 생각합니다.

그런데..............



이런게 있군요... 응?

 이런 물건이 준비되어 있었군요.
WCF Configuration 은 서버측과 클라이언트측 둘다에서 config 파일을 설정할수 있는 GUI 설정입니다.

이것은 자신이 설정한 config 뿐 아니라 설정이 되지 않은 부분까지도 property 형태로 나옴으로써

어려운 WCF의 설정을 도와줍니다.


[상당히 디테일한 부분까지 설정이 가능합니다]


이 매뉴는

VS - > Tools -> WCF Service Configuration Editor 에서 활성화가 가능합니다.


예제

WCF 는 현재 한번에 String 을 8192자 까지만 보낼수 있도록 설정되어 있습니다.
이것을 바인딩 옵션에 추가시켜 , 4MB(4194304) 를 전송할수 있게 옵션을 부여하도록 하겠습니다.

1. config 파일에서 오른쪽 클릭을 하여 Edit Configuration 을 선택합니다.


2. 먼저 서비스 endpoint를 만듭니다. 서비스 타입은 이미 빌드된 WCF dll을 선택하면 됩니다. DLL을 선택하게 되면 그 안에 있는 WCF서비스를 자동으로 보여줍니다.


3. 지정된 contract 를 선택합니다.

4. ServiceType 을 지정합니다. 이번 예제에서는 BasicHttpBinding 을 사용할것이므로 HTTP를 선택합니다.

5. Basic Web Service interoperability 를 선택합니다.

6. endpoint 에 특화시킬 주소를 설정합니다. 기본적으로 Address를 빈칸으로 둠으로써 *의 효과를 가질수 있습니다.

YES 버튼을 눌러 endpoint 를 생성하도록 합니다.

완성된 endpoint 의 정보를 GUI형태로 확인할수 있습니다. 이곳에서 원하는 이름의 endpoint 이름을 부여할수도 있습니다.



이제 바인딩옵션을 추가하도록 하겠습니다.

1. Binding 폴더를 클릭한후 NewBinding Configuration 을 클릭합니다.

2. 만들어진 서비스가 basicHttpBindiing 이므로 이것을 선택합니다.

3. 해당 binding configuration 에서 MaxStringContentLength 를 수정합니다.


4. 해당 BindingConfiguration 을 endpoint에 연결합니다.

이로써 모든 세팅이 완료 되었습니다.

지금까지 작성한 모든 정보는 config 파일에 다음과 같은 형태로 기록됩니다.





Summary

WCF Service Configuration Editor 는 WCF에 모든 옵션을 간편하게 노출시켜 config 파일의 작성을 용이하게 돕는 도구입니다.

WCF는 너무나 옵션이 다양하고 방대해서 , 오타등으로 인해 알수 없는 오류를 유발시켜 스트레스를 주는 경우가 많았는데 ,

그런부분의 니즈를 많이 충족시켜줄 기능이라고 생각됩니다. 상당히 강력하고 사용법 또한 간단하니 꼭 한번 사용해보시기 바랍니다.



앞선 시간들을 통해서, 우리는 테셀레이션에 대해서 꾸준히 살펴보았습니다.
DirectX9 세대에서부터 테셀레이션을 사용했었으며,
ATI 의 일부 그래픽 카드들은 하드웨어 기반의 테셀레이터를 지원했었습니다.

DirectX11의 테셀레이션 작업은 하드웨어 기반으로 처리됩니다.
즉, 이는 무수히 많은 연산을 처리해서 많은 폴리곤을 화면에 보여주겠다는 하나의 의지입니다.
이들이 강력한 이유는 이전 글인 다음을 참고해 주시기 바랍니다.
http://vsts2010.net/331

요약해 보자면,
이제는 텍스쳐링보다는 폴리곤 갯수를 증가시켜서 퀄리티의 향상을 도모하겠다는 것입니다.
사실 이것에 관해서는 많은 우려와 논란이 많았던 것이 사실입니다.
하지만, 현재의 하드웨어 상황은 이들 테셀레이션 기능을 중심으로 변화하고 있는 것이 사실입니다.
아래는 초창기 ATI의 DirectX11 기반의 하드웨어 구조입니다.



ATI의 경우에는 렌더링 목적에 집중하기 위해서 하나의 테셀레이터와 두개의 래스터라이저로 처리를 했었습니다.
물론 이것은 초기 DirectX11을 지원하는 하드웨어의 경우입니다.

ATI가 이런 테셀레이션 기반의 하드웨어를 출시하자,
상대적으로 후발주자였던 NVIDIA의 경우에는 이 테셀레이터를 더 많이 사용한
DirectX11 기반의 하드웨어를 출시하게 됩니다.




위의 빨간 동그라미 영역에 4개씩 보이는 노란 박스가 모두 테셀레이터입니다.
즉 위의 경우에는 16개의 테셀레이터가 존재합니다.( 4개의 래스터라이져 )
NVIDIA의 이런 과감한(?) 테셀레이터의 지원은 ATI의 향후 대응을 기대하게 만들기도 했습니다.

이런 하드웨어적인 논란은 본 글의 취지와는 맞지 않습니다.
이 글은 이런 현재의 상황에 어떻게 대응하는 API 단계의 개발자들을 주요 대상으로 하기 때문입니다.
즉, 어느 것이 더 효과적인지는 분별하기 어렵습니다.
다만 현재까지 나온 의견을 종합해 본다면,
ATI의 경우에는 테셀레이션과 래스터라이져의 본질적인 기능을 중심으로 설계가 되었고,
NVDIA의 경우에는 테셀레이션과 래스터라이져 외에도 GPGPU 환경의 기능을 더 고려해서 설계가 되었다고 합니다.
( NVIDIA의 경우에는 CUDA라는 GPGPU 플랫폼을 XP세대에서부터 강력히 지원했었습니다.^^ )

테셀레이션은 현재까지도 많은 논란이 있습니다.
그 논란의 중심에는 '빠를까?' 라는 의구심과 '엄청난 양의 연산' 에 대한 우려가 있습니다.
또한 하드웨어 기반의 테셀레이션으로의 패러다임 전환이 쉽지 않은 것도 사실입니다.

실제로 테셀레이션 관련 샘플을 실행시켜보면, GPU의 성능에 굉장히 의존적입니다.( 당연한 얘기겠지만요...^^ )
테셀레이션 샘플들은 DirectX11 기반의 하드웨어에서 그렇게 빠르지도, 또한 느리지도 않습니다.
오히려 일반적인 상황에서는 약간의 성능 저하가 일어날 수도 있으며,
최적화를 잘한 경우에는 테셀레이션 처리가 더 느릴 수도 있습니다.
하지만, 이제 하드웨어는 테셀레이터라는 기능을 장착을 했으며,
앞으로는 테셀레이터 기반으로 최적화하는 것이 더 개발 패러다임에 적합할 것입니다.

당분간 개발 패러다임이 과도기적인 상태를 보이겠지만,
이미 그래픽카드의 발전 방향이 테셀레이터 기반으로 변경되고 있다는 것에 우리는 주목해야 합니다.

개발을 진행하다보면, 아무리 훌륭한 툴이라고 하더라도 기능이 부족해서 확장 컴포넌트를 구매해서 쓰는 경우가 있습니다. 저도 예전에 Visual Studio 2008로 개발할 때, DB의 변경사항을 LINQ to SQL의 OR디자이너에 바로 반영하는 기능이 없어서, 검색하다 찾은 확장 컴포넌트를 체험기간만큼 사용했던 기억이 있습니다. 비주얼 스튜디오 2010의 IDE가 매우 훌륭해지기는 했지만, 그래도 좀 더 손맛이 느껴지는 기능을 찾으시는 분들이 있으실 텐데요, 아주 훌륭하고도 공짜인 확장 툴이 가까이 있습니다. 오늘 소개해드릴 Productivity Power Tools가 바로 그것입니다!

설치부터 아주 간단합니다. '도구' 메뉴의 '확장 관리자'를 이용하셔서 '온라인 갤러리'에서 'power tool'이라고 검색만 하시면 찾을 수 있고, 더블클릭만 해주시면 그냥 쉽게 깔립니다. 하지만 기능은 매우 다양합니다. 이제 부터 하나하나 소개 해드리겠습니다.


- 솔루션의 대양을 항해하라, Solution Navigator

좀 복잡한 프로젝트를 하다보면 솔루션에 프로젝트가 아주 많아집니다. 저는 16개정도까지 포함되는 걸 해본적이 있는데요, 이런 솔루션의 대양을 항해할 때는 역시, 나침반이 제맛이죠 :)


어떤가요? 솔루션 탐색기랑 비교해서 좀 이쁘게 생겼나요? 우선 뭔가 틀린 점들이 보이는데요, 하나씩 알아보죠.

1. 클래스의 멤버레벨까지 탐색.


기존의 솔루션 탐색기는 파일레벨까지 탐색이 가능했지만, Solution Navigator(이하 네비로 줄여씁니다)에서는 클래스의 멤버까지 탐색이 가능합니다.

2. 빠른 검색.

네비를 보면, 검색어를 입력할 수 있는 텍스트박스가 하나 있습니다. 여기에 Cl이라고 입력하면(씨엘...?), 다음과 같이 Cl이 포함되는 항목을 모두 찾아줍니다.


3. 호출 계층구조 바로 보기

Visual Studio 2010에 추가된 호출 계층구조 보기가 네비안에 통합되어 있습니다. 네비안에서 항목을 하나 선택하면, 오른쪽 끝에 조그만 아이콘이 하나 생깁니다. 이 아이콘을 누르면, 네비의 항목이 그 항목을 원점으로 해서 다시 표시됩니다. 예를 들어서 Class1의 PrintCount()메서드를 원점으로 해서 보면 아래와 같습니다.


이 메서드가 포함하는 것과, 참조하는 것들, 누가 이 메서드를 호출하는지, 이 메서드가 어떤 것들을 호출하는지 등을 한번에 파악할 수 있죠.

4. 네비가 표시할 항목 필터링

네비에서 솔루션항목 바로 아래에 보면 4가지 커맨드가 있습니다. All은 말 그대로 모든 항목을 표시하는 거구요, Open은 아래처럼, 지금 코드 편집기에서 열려있는 항목만 표시합니다.


그리고 Unsaved는 아래처럼 변경사항을 저장하지 않은 항목만 보여줍니다.


저장하지 않은 항목의 탭을 붉은색 점으로 강조하는 것도 새로 추가된 기능입니다. 그리고 Edit는 한번이라도 수정되었던 파일을 표시합니다.

5. 이미지 썸네일 제공

네비에 에서 솔루션에 포함된 이미지 파일에 마우스를 올리면, 아래와 같이 이미지의 썸네일을 표시해줍니다.


6. 코드 편집기에서 즉석 호출

코드 편집기에서 네비의 기능을 즉석 호출할 수도 있는데요, 예를 들어서 PrintCount메서드내에 커서를 두고 'Ctrl + 1'키를 누르면, PrintCount메서드와 관련된 항목들이 바로 나타납니다.


그리고 'Ctrl+2'를 누르면, 현재 코드 편집기에서 열려있는 파일의 모든 클래스에 대한 정보가 바로 나타납니다.




- Visual Studio를 Tab!

비주얼 스튜디오의 코드편집기에서 여러파일을 작업하려면 여러파일을 열어놓고 탭으로 파일간의 이동을 하면서 작업을 해야 합니다. 그만큼 많이 사용해야 하는 탭인데요. 이 탭이 어딘가 모르게 좀 불편한 면이 있었습니다. 그래서 Power Tools에서는 이 탭에 대한 지원이 막강해졌습니다.

1. 다양해진 옵션


옵션에 들어가면 Power Tools탭안에 Document Tab이라는 항목이 따로 있습니다. 그리고 미리 정의된 프리셋을 제공하는데요, Visual Studio 2008부터 아주 다양한 프리셋을 지원합니다.

2. Option 1 : Web Browser: Scrollable tab well


이 탭은 브라우저 처럼, 탭에 해당항목의 아이콘이 붙습니다. 그리고 고정시킬 수도 있는데요, 고정시킨 탭은 움직일 수 없습니다. 그리고 'Close All But Pinned'와 같이 고정된 탭을 제외하고 모두 닫기 같은 옵션도 제공합니다. 그리고 옵션에서 'Show pinned tabs in a separate row'를 체크하면 아래와 같이 고정된 탭만 구분해서 볼 수도 있습니다.


3. Option 2 : Scrollable Tab Well: Sorted by project


이 옵션을 사용하면, 위 사진과 같이 프로젝트 별로 탭의 색깔을 구분하고 정렬해서 보여줍니다. 15개까지 다른 프로젝트를 지원합니다.

4. Option 3 : Vertical Tab Well: Color coded and sorted by project


이 옵션을 사용하면, 기존의 수평이 아닌, 수직으로 탭을 나열해서 보여줍니다. 이렇게 하면 훨씬 많은 탭을 한번에 볼 수 있다는 장점이 있습니다 :)

5. Option 4 : Dynamic Tab Well: Removes tabs based on usage

이 옵션은 좀 똑똑한 옵션인데요. 탭이 많아서 한번에 표시하지 못할 경우, 가장 적게 사용한 탭 순으로 먼저 사라지게 하는 것입니다. 쫌 괜찮죠 :)


- 마치면서

오늘은 Power Tools의 Solution Navigator와 Tab에 대해서 알아봤습니다. 이 것만 해도 상당히 유용한 기능인데요, 소개해드릴 기능이 조금 더 남았습니다. 그럼, 다음에 또 뵙죠 :)

WCF Troubleshooting (1)

WCF 2010. 11. 19. 09:00 Posted by 알 수 없는 사용자
 
와우~ 정말 오랜만에 포스팅을 하네요 ^^;;
여러 가지 일 때문에 포스팅을 하지 못했는데 이제 다시 힘을 내서 그 동안 못했던 포스팅을 해보도록 하겠습니다.
어느새 계절은 겨울이 되어 날씨가 많이 추워졌는데, 모두 건강 주의 하시길 바랍니다.

이번 포스팅 부터는 WCF 를 이용하여 서비스를 구현하는데 있어 발생할 수 있는 여러 가지 예외나 에러를 어떻게 처리할 수 있는지에 대한 얘기를 해 볼까 합니다.

WCF 서비스와 같이 분산 어플리케이션을 개발할 때는 항상 에러나 예외의 원인을 찾거나 디버깅하기가 조금 애매하죠. 로컬에서 개발할 때에는 문제가 없다가도 실제 서버에 배포를 하고 나면 발생하는 예외나 에러는 개발자를 난감하게 만들기도 합니다.

그래서~ 이번 포스팅 부터는 WCF 에서 발생하는 예외를 어떻게 핸들링 할 수 있는지, 그리고 에러에 대한 진단을 하기 위해 어떤 방법을 사용할 수 있는지에 대한 내용으로 진행을 해볼까 합니다.


Fault Message 와 Exception

.NET 어플리케이션은 에러가 발생했을 때, 에러에 대한 내용을 알리기 위해 Exception 클래스를 사용합니다. 이는 물론, WCF에서도 예외가 아닙니다. 다만, 이러한 에러의 내용을 클라이언트에 전달하기 위해서 Fault Message 를 사용한다는 것이 조금 다르긴 하죠.
쉽게 얘기해서, 서비스에서 클라이언트로 어떤 데이터를 넘겨줄 때 직렬화를 사용하는 것처럼, 에러 메시지,, 그러니깐 Exception 오브젝트도 직렬화를 한 후에 클라이언트로 전달한다고 생각하면 된다는 것입니다.

Fault Message는 다음과 같은 XML 형태로 클라이언트로 전달되는데, 이는 표준 SOAP Fault 메시지(Ver 1.2)의 스키마와 같습니다.

<Body>
   <Fault>
      <Code>
         <Value>s:Sender</Value>
      </Code>
      <Reason>
         <Text xml:lang="en-US">…</Text>
      </Reason>
      <Detail>
         <ErrorInfo xmlns="http://Service1">
            <Info>…</Info>
         </ErrorInfo>
      </Detail>
   </Fault>
</Body>


각 element에 대한 자세한 설명은 다음의 링크에서 확인하시면 될 것 같습니다. (http://www.w3.org/TR/soap12-part1/#soapfault) 근데, 자료가 영문이라 보기 싫으신 분들 있으실 겁니다. 저도 그렇지만~ 일단, 글이 너무 많으면 부담되서…(그것도 영문… OTL)

그래서, 다음과 같이 간단하게 정리를 해보았습니다.

Element

설명

Fault

Fault 메시지의 root element

Code

예외가 발생한 원인을 나타낸다.

Reason

예외의 자세한 내용을 보여준다.

Detail

예외의 추가적인 정보를 나타낸다.


이 정도만 체크하고, 다음으로 넘어가기로 하죠~ 엣헴~ ;;;;

기본적으로 WCF 서비스에서 예외가 발생하면, 자세한 정보가 담겨있는 Fault 메시지가 전달되는 대신에 다음과 같이 Detail element가 빠져있는 Fault 메시지를 전달합니다.

<s:Fault>
   <s:Code>
      <s:Value>s:Receiver</s:Value>
      <s:Subcode>
         <s:Value xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">a:InternalServiceFault
         </s:Value>
      </s:Subcode>
   </s:Code>
   <s:Reason>
   <s:Text xml:lang="en-US">The server was unable to process the request due to an internal error. For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the &lt;serviceDebug&gt; configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework 3.0 SDK documentation and inspect the server trace logs.</s:Text>
   </s:Reason>
</s:Fault>


Text element의 내용을 자세히 보면, WCF 서비스 개발을 하면서 한번쯤 봤을 법 한 메시지가 적혀있는 것을 확인 할 수 있습니다. 이 Fault 메시지는 닷넷에서 처리할 수 없는 범주의 예외가 발생했거나, 예외 정보를 공개하지 않도록 설정되어 있는 경우에 생성되는 메시지 입니다.

기본적으로 WCF 서비스는 예외 정보를 공개하지 않도록 설정되어 있으므로, 개발을 하는 동안 자세한 예외 정보를 받기를 원한다면 이 설정 값을 바꿔주어야 합니다.

서비스의 환경 설정 파일(web.config/app.config) 에서 behavior element 밑에 있는 serviceDebug element 의 includeExceptionDetailInFaults의 속성값을 true로 바꿔주면 되는 것이죠.

<behaviors>
   <serviceBehaviors>
      <behavior name="MyBehavior">
         <serviceMetadata httpGetEnabled="true"/>
         <serviceDebug includeExceptionDetailInFaults="true"/>
      </behavior>
   </serviceBehaviors>
</behaviors>

 
이와 같이 설정을 한 후에 예외를 발생시켜 볼까요? 서비스에 두 숫자를 받아 나눗셈을 한 결과를 리턴하는 "Divide" 라는 메서드를 만들었습니다. 그리고, 간단하게 예외를 발생시키기 위해서, 0으로 다른 숫자를 나누도록 파라미터를 넘겨주었습니다. 그러면, 당연히 DivideByZeroException 이 발생하겠죠~

그랬더니~ 다음과 같은 Fault Message 를 클라이언트로 전송해 주는 것을 볼 수 있었습니다.
아~ 참고로 이 메시지를 확인하기 위해서 저는 Fiddler(피들러)를 사용했습니다.

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"
xmlns:a="http://www.w3.org/2005/08/addressing">
   <s:Header>
      <a:Action s:mustUnderstand="1">
         http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/
dispatcher/fault
      </a:Action>
      <a:RelatesTo>urn:uuid:8e5a89f4-b765-45e3-b343-26c07fde57dd</a:RelatesTo>
   </s:Header>
   <s:Body>
      <s:Fault>
         <s:Code>
            <s:Value>s:Receiver</s:Value>
            <s:Subcode>
               <s:Value xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">
                 
a:InternalServiceFault
               </s:Value>
           
</s:Subcode>
         </s:Code>
         <s:Reason>
            <s:Text xml:lang="en-US">Attempted to divide by zero.</s:Text>
         </s:Reason>
         <s:Detail>
            <ExceptionDetail xmlns="http://schemas.datacontract.org/2004/07/System.ServiceModel" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
               <HelpLink i:nil="true"/>
               <InnerException i:nil="true"/>
               <Message>Attempted to divide by zero.</Message>
               <StackTrace>
at Wcf_TroubleShooting.Service1.Divide(Int32 numerator, Int32 denominator) in C:\Users\RuAA\documents\visual studio 2010\Projects\Wcf-TroubleShooting\Wcf-TroubleShooting\Service1.svc.cs:line 19&#xD;
at SyncInvokeDivide(Object , Object[] , Object[] )&#xD;
at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]&amp; outputs)&#xD;
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&amp; rpc)&#xD;
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc&amp; rpc)&#xD;
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc&amp; rpc)&#xD;
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc&amp; rpc)&#xD;
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc&amp; rpc)&#xD;
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc&amp; rpc)&#xD;
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc&amp; rpc)&#xD;
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc&amp; rpc)&#xD;
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc&amp; rpc)&#xD;
at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
               </StackTrace>
               <Type>System.DivideByZeroException</Type>
            </ExceptionDetail>
         </s:Detail>
   </s:Fault>
   </s:Body>
</s:Envelope>



딱 봐도 아시겠지만, 이 전에 봤던 Fault Message에 비해 확실히 더 자세한 내용을 담고 있는 것을 볼 수 있습니다.

사실 이러한 내용들을 다 알 필요는 없습니다. 닷넷으로 클라이언트를 개발한다면 다른 예외와 마찬가지로 try/catch 문을 이용하여 예외를 처리할 수 있을 테니까 말이죠~ 하지만, 개인적으로 이런 기본적인 내용들도 중요하다고 생각하는지라 하나의 포스팅을 통해 정리를 해보았습니다.

아직 할 얘기들이 많지만 너무 길어지면 지루해질 것 같아 여기서 줄일려고 합니다.

다음 포스팅에선 FaultContract 에 대한 설명과 함께 이를 이용해서 에러에 대한 메세지를 정의하고, 이를 클라이언트에 전달하는 방법, 그리고 그외에 에러를 핸들링 하는 방법에 대한 이야기를 써 볼까 합니다.

다음 포스팅을 기대하시는 분은 없으실 거라 예상이 되어 기대해달란 말을 하긴 어려울 것 같지만, 최대한 아주 아주 빠른 시일 내에 업데이트 할 수 있도록 하겠습니다. ^^

Visual Studio 31 (3) - Temp Project

Visual Studio 2010 2010. 11. 18. 09:00 Posted by 알 수 없는 사용자

개발하다 보면, 지금 작성하고 있는 알고리즘이 내가 원하는 대로 작동하는지 헷갈리기 시작합니다. 하지만, 프로젝트의 일부로 속하는 이 알고리즘이 제대로 작동하는지 알 수 있는 방법은 유닛테스트 외에는 직접 실행하는 방법외에는 없습니다. 알고리즘이 UI나 데이터베이스 같은 다른 부분과 긴밀하게 연계되어 있기 때문에 알고리즘만 따로 테스트할 방법이 마땅히 없으며, UI정도라도 배제하고 테스트하는 방법이 바로 유닛테스트를 활용하는 방법인거죠.

그래서 간단한 예제 데이터를 가지고 확인하고 싶을 때는 콘솔 어플리케이션 프로젝트를 활용하기도 합니다. 알고리즘을 제외한 모든 걸 최고로 단순화 시켜놓고 알고리즘 자체만 가지고 테스트를 진행할 수 있기 때문이죠. 그런데, 이 콘솔 어플리케이션을 애용하다보면, 다음과 같은 상황이 발생합니다.


'ConsoleApplication'뒤에 붙는 숫자가 계속해서 늘어만 가고, 프로젝트 폴더는 점점 더 지저분 해지는 것이죠. 이런 상황을 미연에 방지할 수 있는 기능이 Visual Studio에 있습니다. 어떤 기능인지 한번 알아보시죠.


- 왔다 가는 인생 흔적을 남기지 않도록.

'도구'메뉴에서 '옵션'을 선택하면, 다음과 같은 '옵션'창이 나타납니다.


그리고 '환경'탭을 시작으로 아래쪽으로 많은 옵션이 있죠. 평생 저런 옵션 다 만지는 일이 있을까 싶을 정도로 말이죠. 하지만... '환경'에서 한 칸만 위로 올라가보면...?



'프로젝트 및 솔루션'이라는 탭이 숨어있습니다!! 바로 이 탭이 오늘 소개하려는 기능과 관련이 있습니다. 항목을 찬찬히 살펴보다 보면, '만들어질 때 새 프로젝트 저장'이라는 항목이 있습니다. 이 항목이 기본으로 체크되어 있는데요, 이 항목의 체크를 해제하고 확인을 누릅니다.

그리고 새프로젝트 대화상자를 열어보면,


음... 뭐가 바뀐 걸까요? 한번 이 그림을 가지고 묵상을 해보시기 바랍니다...

답을 알아내셨나요? 힌트를 드리자면, 아까 분명히 탐색기를 보여드렸을 때, 'ConsoleApplication9'까지 있었는데, 새프로젝트 대화상자에 나타난 것은 'ConsoleApplication10'이 아니라 'ConsoleApplication1'입니다.

네, 바로 임시 프로젝트 공간에 프로젝트를 생성하기 때문입니다. 그래서 대화상자를 보시면, 경로를 명시하는 부분이 사라진 것을 확인하실 수 있습니다. 그럼 프로젝트를 생성하겠습니다.

그럼 이제 제가 거짓말 하는 것이 아님을 보여드릴 차례네요. 다음과 같이 프로젝트에 오른쪽 버튼을 클릭하고 '윈도우 탐색기에서 폴더 열기'를 선택합니다.


그러면, 프로젝트 폴더가 탐색기에서 열립니다. 탐색기의 경로를 유심히 보시죠.


Local밑의 Temporary Projects라는 경로가 보이실 겁니다. 바로 여기에 생성되었다가, 솔루션을 닫을 때 저장하지 않으면 사라지는 것이죠. 그럼 솔루션을 닫아볼까요?


저장할 것인지, 버릴 것인지 물어봅니다. 버리면 그냥 사라지는 거죠. 모든 기능이 그렇 듯이 임시 프로젝트에도 몇가지 제약 사항이 있는데요. 첫 번째는, 단일 프로젝트만 가능하다는 것입니다. 임시 프로젝트에 새 프로젝트를 추가하려고 하면 다음과 같은 메세지를 볼 수 있습니다.


그리고 두 번째로, 경로가 필요한 웹 어플리케이션 같은 프로젝트 타입에는 사용할 수 없다는 것입니다.


- 마무리

임시 프로젝트 기능을 통해서 프로젝트 폴더를 깔끔하게 유지하시기 바랍니다. 그럼 다음에 또 뵙죠~ :)

MSDN을 보다 보니 C++/CLI의 델리게이트에 네이티브용 함수를 할당할 수 있는 방법이 있어서 소개합니다. 아래의 코드는 MSDN에 있는 것입니다.

 

#pragma unmanaged

extern "C" void printf(const char*, ...);

class A {

public:

   static void func(char* s) {

      printf(s);

   }

};

 

#pragma managed

public delegate void func(char*);

 

ref class B {

   A* ap;

 

public:

   B(A* ap):ap(ap) {}

   void func(char* s) {

      ap->func(s);

   }

};

 

int main() {

   A* a = new A;

   B^ b = gcnew B(a);

   func^ f = gcnew func(b, &B::func);

   f("hello");

   delete a;

}

< http://msdn.microsoft.com/ja-jp/library/9cy3ccxx%28v=VS.80%29.aspx >

 

위 코드 중 #pragma unmanaged 지시어 이하는 컴파일러에서 비관리코드로 취급합니다. 그리고 #pragma managed 이하는 관리코드로 취급합니다. 내용이 간단하고 어려운 부분이 없기 때문에 따로 자세한 설명은 생략하겠습니다.

 


C++/CLI는 단순하게 닷넷 플랫폼에서 사용할 수 있는 C++ 언어라기 보다는 C++ 언어의 부족한 부분을 진화 시킨 언어라고도 생각할 수 있는 부분이 꽤 있습니다. 그러나 C++/CLI는 C++과 C#의 중간의 애매한 위치에 있어서 양쪽 프로그래머 모두에게 별로 호응을 받지 못하는 것 같습니다. 그래서 C++/CLI 관련 글을 제가 처음에 생각했던 것보다는 조금 일찍 끝낼려고 합니다.

C++/CLI를 사용하는 대부분의 프로그래머들은 아마 기존의 비관리 코드를 관리코드에서 사용하고 싶을 때라고 생각합니다. C++/CLI의 기능 소개는 이번으로 일단 끝내고 앞으로는 비관리코드와의 연계에 대해서 실제 사례 보여주면서 설명하려고 합니다.


사례는 오픈 소스 네트워크 라이브러리인 HalfNetworkC++/CLI를 사용하여 관리코드에서 사용할 수 있도록 wrapping한 후 이것을 관리코드에서 사용할 예정입니다.

HalfNetwork는 온라인 게임 서버 프로그래머인 임영기님이 만든 것으로 ACE 라는 오픈 소스 네트워크 라이브러리를 사용하기 편하게 만든 라이브러리입니다.

 

소스 위치 http://code.google.com/p/halfnetwork/

문서 http://code.google.com/p/halfnetwork/w/list http://jacking.tistory.com/category/HalfNetwork

임영기님 블로그 http://javawork.egloos.com/

 

요즘 공부할 것은 너무 많은데 따라갈 시간은 부족해서 다음 글은 언제쯤 올리지 정확하게 알 수 없지만 최대한 빨리 다음 글들을 올려서 C++/CLI을 2010년 안에는 끝내고 내년에는 새로운 주제로 시작하겠습니다^^

 

Visual Studio 31 (2) - Startpage

Visual Studio 2010 2010. 11. 15. 09:00 Posted by 알 수 없는 사용자

Visual Studio 31~! 오늘은 그 두번째 시간으로 비주얼 스튜디오를 켜면 항상 보게 되는 시작 페이지에 대해서 이야기 해보겠습니다.


- 기존 작업목록을 관리하기 시작~!

우선 '최근에 사용한 프로젝트' 목록부터 살펴보죠.


비주얼 스튜디오 2008까지는 '최근에 사용한 프로젝트'목록을 편집할수가 없었습니다. 그래서 아무리 자주 작업하는 프로젝트라고 하더라도 잠깐 다른 작업하면서 프로젝트 열고, 생성하다보면 목록에서 사라지는 때가 있습니다. 그럴때는 다시 경로 찾아가서 열어야 했죠. 이제 비주얼 스튜디오 2010에서는 자주 작업하는 프로젝트나 중요한 프로젝트는 목록에 고정시켜놓을 수 있습니다. 항목의 왼쪽에 핀이 있는데 그걸 꾹~ 눌러주면, 프로젝트가 아무리 많이 생성되고 열리더라도 항상 그자리를 지키게 됩니다. :)


그리고 조금 더 편리한 기능도 추가되었는데요, 항목에 마우스 오른쪽 버튼을 눌러보면, 프로젝트의 폴더를 열거나, 목록에서 제거하는 것도 가능합니다. 기존 버전에서는 지원되지 않았었죠.


그리고 시작 페이지에 추가된 또 하나의 작은 기능. 프로젝트를 로드한 뒤에 페이지를 닫을 것인지, 시작할 때 페이지를 표시할 것인지를 선택할 수 있게 되었습니다.


- 시작 페이지를 내 맘대로 설정하기 시작~!


'도구'메뉴에서 '옵션'항목을 선택해서 '옵션'창을 띄우면, '환경'탭 안에, '시작'항목이 있습니다. 여기에 보면, 비주얼 스튜디오를 시작할 때, 시작 페이지를 어떻게 할 것인지에 대한 옵션이 있습니다. 마지막으로 작업했던 솔루션을 로드하게 할 것인지, '새 프로젝트'대화 상자를 띄울 것인지, 등등등. 이 옵션은 기존에도 있었습니다. :) 위 그림에서 비주얼 스튜디오 2010부분을 유심히 보시면 '시작 페이지 사용자 지정'이라는 항목이 있습니다. 시작 페이지도 마음대로 바꿀 수 된거죠! 그럼 다른 사람들이 만든 시작 페이지를 받아서 세팅해보겠습니다.

'도구'메뉴를 통해서 '확장관리자'를 띄우면, 온라인에 다른 사람들이 만들어서 공개해놓은 확장을 검색하고 설치할 수 있습니다. 검색란에 'startpage'라고 입력해보면,


위와 같이 몇가지 시작페이지가 검색됩니다. 여기서 'ItaStartPage'를 한번 설치해보겠습니다. '다운로드'버튼을 누르고,


이어서 나오는 창에서 '설치'를 눌러서 확장을 설치합니다. 그리고 비주얼 스튜디오를 재시작해서 확장이 검색되도록 합니다.


그리고 다시 시작페이지 설정으로 들어와서 '시작 페이지 사용자 지정'항목을 보면, 아까 설치했던 확장이 검색되는 것을 볼 수 있습니다. 확장을 선택하고 '확인'을 눌러서 설정을 적용하면,


아하~! 이 확장 시작페이지는 시작 페이지에 배경 이미지를 설정할 수 있군요 :) 참고로 'ItaStartPage'를 만든 분이 'ItaBackgroundImage'라는 것도 만드셨는데, 설치해보니...


이렇게 코드 편집기 창에도 배경이미지를 설정할 수 있더군요! :)


- 다음 시간에~

그동안 아무 생각없이 매일 대면하던 시작 페이지도 이런저런 기능 변화를 통해서 편리하게, 그리고 내 입맛에 맞게 변경할 수 있게 변했네요. 그럼 다음 시간에 또 뵙죠 :)

[발표자료] 예제로 느껴보는 다이렉트X 11의 매력

DirectX 11 2010. 11. 13. 09:00 Posted by 알 수 없는 사용자

안녕하세요. 알콜코더 민군입니다. 


지난 11월 9일날 양재동에서 있었던 

'C++&게임 개발자를 위한 개발 생산성 및 퍼포먼스 향상 세미나' 에서 제가 발표했던 발표 자료입니다. 


부족한 발표였는데도 참석해 주신분들에게 다시 한번 감사드립니다. 꾸벅. (^^)(__)



Visual Studio 31 (1) - 시작, 그리고 Intellisense

Visual Studio 2010 2010. 11. 11. 09:00 Posted by 알 수 없는 사용자


안녕하세요~ 워너비입니다. 이번에 새로운 시리즈를 하나 시작하게 되었습니다. 이 시리즈는 이름하여 'Visual Studio 31'! 골라먹는 재미가 있는 아이스크림처럼, 비주얼 스튜디오 2010도 엄청나게 다양한 기능 속에서 필요한 기능을 골라쓰는 재미가 있습니다. 몰라서, 어려워서 못 썼던 기능이 있으시다면, 이 시리즈를 통해서 좀 더 친숙해지셨으면 하는게 이 시리즈의 목표입니다. 목표가 달성될지는 살짝 의문이네요 :)


- 오늘은 그 첫 시간.

자, 오늘은 Visual Studio 31의 첫 번째 시간으로 인텔리센스에 대해서 알아보겠습니다. 인텔리센스는 비주얼 스튜디오의 얼굴이라고도 할 수 있죠. 모든 개발자가 가장 많이 활용하며, 코딩에서 가장 편리함을 제공하는 기능이기 때문이죠. 이 인텔리 센스가 비주얼 스튜디오 2010에서 어떻게 달라졌을까요? 비주얼 스튜디오 2008의 인텔리센스와 Before/After를 비교해보도록 하죠 :)


- 관련있는 것들만 보여주는 쎈쓰!



차이점을 발견하셨나요? VS2008에서는 'Console'을 입력하면, 전체목록에서 'Console'과 정확히 일치하는 곳에 포커스를 둡니다. 그런데 포커스를 두기만 할 뿐, 아무런 것도 도와주지 않았습니다. 그런데 VS2010에서는 'Console'을 입력하면, 'Console'이 포함되는 것들만 추려서 인텔리센스에 보여줍니다. 인텔리센스가 많이 똑똑해졌죠? 이제 사용자에게 필요한 정보만 최대한 추려서 보여주는 거죠. 자, 그럼 인텔리센스의 쎈쓰! 가 여기까지 일까요?


- 이름의 일부로도 찾아주는 쎈쓰!


이번에는 어떤 차이점이 있을까요? 기존에는 정확하게 찾으려는 항목과 입력하는 항목의 시작이 같아야만 인텔리센스에서 해당항목을 찾아줬습니다. 그런데 저 처럼 기억력이 저주받은 사람들은 참 슬픈 코딩을 해야했죠. 다른 방법이 있을지도 모르겠지만, 초짜인 제가 했던 방법은 MSDN에 들어가서 얼추비슷한 키워드로 검색을 해서 찾는 방법이었습니다. 그런데 이제 VS2010은 저 같은 초짜&저주받은 기억력 세트를 가진 사람들을 위해서 사용자가 입력하는 문자를 포함하는 항목을 모두 보여주도록 향상되었습니다. 'Color'만 입력하더라도 VS2010은 'Color'가 포함되어있는 'ConsoleColor'를 찾아서 보여주는 거죠 :) 점점 마음에 듭니다.


- 파스칼 케이스로도 찾아주는 쎈쓰!

파스칼 케이스는 뭘까요? 일종의 네이밍 규칙인데요, 서로 다른 단어를 조합해서 메서드 이름을 만들거나 할때, 각 단어의 맨앞글자를 대문자로 표기하는 방법입니다. Console과 Color를 조합해서 'ConsoleColor'를 만드는 것 처럼 말이죠.


기존에는 위에서 설명드렸듯이 시작부터 정확하게 같아야지만 인텔리센스에서 항목을 찾을 수 있었습니다. 하지만 똑똑해진 VS2010에서는 파스칼 케이스의 각 대문자만 입력해도 찾아준다는 거죠. 'CC'를 입력했다면, 'CC'가 직접 포함되는 항목부터, 'C'가 파스칼 케이스로 연속 두번 포함되는 항목도 모두 찾아서 보여줍니다. 이름이 긴 항목을 자주 찾는다면 매우 편리하겠죠 :)


- 없는 클래스도 보여주는 쎈쓰!

TDD를 하려고 할때나, 먼저 코드의 윤곽을 짜놓고 필요한 클래스를 생성하는 식의 프로그래밍을 할때는 존재하지 않는 타입의 객체를 생성해서 사용하게 됩니다. 이런 방식은 어느정도 장점도 가지고 있는데요, 우선 생성하고 하는 클래스의 구체적인 부분에 대해서 생각하는 대신에, 지금 짜려고 하는 코드의 흐름에 우선적으로 집중할 수 있기 때문입니다. 코드의 흐름에 집중하다가, 클래스를 정의하려고 하면 집중의 전환이 일어나기 때문에 그만큼 비효율적인 작업이 될 수도 있습니다.


존재하지 않는 App라는 클래스의 객체를 생성하려고 하면, 기존 버전에서는 전혀 인텔리센스의 지원을 받을 수 없었습니다. 그래서 일일이 쌩코딩을 해야 했었죠. 하지만, VS2010이 출동한다면? 존재하지 않는 타입이라고 하더라도 일단 new를 만나면 존재하는 타입인 것 처럼 인텔리센스에서 보여줍니다. 많이 편리해졌죠~? :)


- 개발자의 취향에 따라 맞춰가는 쎈쓰!



위 Before/After는 모두 VS2010의 캡쳐입니다. 무슨 차이점이 있을까요? Before에서는 입력하는 것과 일치하는 항목에 강조가 되어있고, After에서는 맨위에 별도의 칸이 한칸 추가되어 있으며, 인텔리센스에 강조가 약하게 되어있다는 점이 차이점입니다. After에서 볼 수 있는 것이 VS2010의 인텔리센스에서 제공하는 '서제스천 모드'를 사용한 것입니다. 바로 검색 사이트의 검색창을 떠올리시면 됩니다. 거기서 검색어를 입력하면, 입력하는 검색어와 가장 비슷한 항목을 보여주지만 그 항목이 검색어를 입력하는데 아무런 영향을 주지는 않습니다. 선택하지 않으면 그만이라는 거죠. 그러면, 둘은 어떤 차이가 있을 까요? 기본적인 인텔리센스와 서체스천 모드를 사용한 인텔리센스에서 'App'를 입력하고 Space키를 눌러보면 그 결과를 확인할 수 있습니다.

App라는 클래스는 존재하지 않기 때문에, 기본 모드에서는 가장 비슷한 AppDomain을 선택해버립니다. 하지만, 서제스천 모드에서는 추천항목을 보여줄 뿐, 사용자의 입력에 관여하지 않기 때문에 그냥 App그대로 남은 걸 보실 수 있습니다. 서제스천 모드를 사용하려면, 코드 편집창에서 'Ctrl + Alt + Space'를 누르면 됩니다. 그리고 서제스천 모드에서 기본 모드처럼 추천 항목을 입력하고 싶으면 'Tab'키를 누르면 됩니다 :)


- See you next time :)

오늘은 첫 시작으로 인텔리센스에 대해서 알아봤습니다. 앞으로도 계속해서 골라먹을 수 있는 비주얼 스튜디오 2010의 기능에 대해서 소개해 드릴예정이오니~, 기대해주시기 바랍니다. :)

119일에 오후 2시에 양재역 엘타워에서 한국 마이크로소프트와 인텔이 주최하고 월간 마이크로소프트웨어에서 주관한 ‘C++ & 게임 개발자를 위한 개발 생산성 및 퍼포먼스 향상 전략 세미나가 열렸습니다.

http://new.imaso.co.kr/seminars/game

 

아직 가을이지만 겨울이라는 생각이 들 정도로 추운 날씨였지만 많은 개발자 분들이 참석하셨습니다. 저는 요즘 회사가 바쁜 관계로 오전까지 일하다가 가서 좀 늦었더니 세미나 장은 이미 만원이더군요.

 


이 날 세미나에서 팀블로그에서 DX11을 연재하고 계신 박민근님과 제가 강연자로 참여했습니다. 박민근님은 예제로 느껴보는 DX11의 매력이라는 세션을 통해서 실제 DX11의 새로운 기능이 어떻게 사용되는지 보여주셨습니다. 원래 이날 실제 코드를 컴파일 해서 실행되는 모습을 보여 줄 예정이었지만 DX11을 지원하는 노트북을 구하지 못해서 안타깝게 집에서 찍은 영상으로 대체해서 보여주었습니다. 아마 다음에 DX11 관련 세미나가 있을 때는 컴파일 해서 돌아가는 모습을 볼 수 있을 테니 기다려주세요^^

제 시간에 가지 못해서 뒤에서 사진을 찍으니 박민근님이 작게 나오는군요^^;


15분인가 20분 정도 남을 때부터 5분 간격으로 남은 시간을 알려주더군요


저는 ‘C++ 프로그래머가 알아야 할 병렬 프로그래밍 상식이라는 주제로 병렬 프로그래밍과 관련된 하드웨어, 플랫폼, 아키텍처 그리고 용어나 Tip을 정리한 세션이었습니다. 강연 중 중앙의 스크린이 잠시 나가기도 하고고 10분을 남겨진 시점에서 노트북 밧데리가 얼마 남지 않았다는 경고 창이 발생하는 돌발 상황이 발생했지만 무사히 강연을 마쳤습니다.




박민근님과 저 이외에 인텔에서 두 분이 인텔의 병렬프로그래밍 관련 툴이나 라이브러리를 소개하셨습니다.


행사장에서는 Visual Studio 책자를 나누어 주고 있었고, 세미나가 끝난 후에는 제가 적은 C++0x 책도 배포되었습니다.^^


새로운 시대, 새로운 기술, 접근성을 높인 기술, Microsoft Research!!

이전 포스트에서 잠깐 알아보았듯이, Microsoft Research 프로젝트는 꾸준히 그 개수가 늘어나고 있으며, 지금 여러분이 사용하는 기술과 크게 동떨어진 기술이 아니라는 것을 알았습니다. .NET을 감싸주는 탄탄한 인프라가 그것을 증명해 주고 있으며, 이제는 Microsoft Research 에서 실험적이고 미래지향적인 기술을 꾸준히 연구를 하고 있습니다.

오늘 소개해 드릴 기술도 마찬가지로, 없어도 개발하는데 지장은 없는 그런 그저 그런 기술이 될 수 도 있습니다. 하지만, 기술자로서 기술을 떠나서 미래의 트랜드를 짐작해본다는 의의로 보시면 좋을 것 같습니다.^^

   

i2i - 3D Visual Communication

http://research.microsoft.com/en-us/projects/i2i/

요즘은 3D 가 대세죠. 영화에서부터 게임, TV 까지 입체영상으로 감상하는 3D 기술이 무척 빠르게 발달해왔던 것 같습니다. 하드웨어적으로 3D를 지원하지 않아도, 소프트웨어적으로 3D 로 변환하는 인코더도 나와있는 상태이며, 이런 기술에 Microsoft Research 가 꾸준히 기술을 개발하고 있습니다.

   

이런 3D 기술은 비디오 촬영을 3D 카메라로 촬영하여 하는 방식이 있고, 소프트웨어로 실시간 3D 로 랜더링 또는 변환하는 기술이 있습니다.

현재 "i2i - 3D Visual Communication" 는 이런 기술을 사용하기 위한 SDK(Software Development Kit) 을 이미 Microsoft Research 에서 내놓았습니다. 완성된 것은 아닌 듯 한데, 실험 정신이 강하신 분들은 미리 체험을 해 보셔도 좋을 겁니다.

   

Infer.NET

http://research.microsoft.com/en-us/projects/infernet/

베이시안 확률(Bayesian probability)은 통해 추론과 확률을 통해 해석하는 연구 분야입니다. 저도 이 분야에 대해서는 잘 알지는 못합니다만, 아래의 링크에서 이미 어느 정도의 개발 킷을 공개하고 있습니다. 관심 있는 분들은 사용해 보시고 트랙백 부탁 드립니다. ^^

http://research.microsoft.com/en-us/um/cambridge/projects/infernet/

   

   

Microsoft Visualization Language - The Vedea Project

http://research.microsoft.com/en-us/projects/vedea/

시각화 언어라는 새로운 실험적인 프로젝트입니다. Computational Science Laboratory 에서 이와 유사한 분야에 대해 연구하는 활동이 활발해 보입니다. 이 프로젝트는 더 나아가 자연과학, 생물학 등 다양한 분야까지 연구를 진행하는 프로젝트인 것 같습니다.

   

Moles - Isolation framework for .NET

http://research.microsoft.com/en-us/projects/moles/

Moles 는 일명 Mock-up 과 같은 가상의 객체를 사용하여 테스팅을 하거나 객체를 만드는 Dynamic Runtime 또는 Dynamic Proxy 등의 기술과 접목됩니다. 이 부분에서 예전에 포스팅을 한 내용을 참고하시기 바랍니다.

[Testing] Moq.NET (T/B Driven Development)
[Testing] BDD (Behavior-Driven Development–행위 주도 개발)
[Testing] TDD (Test-Driven Development-테스트 주도 개발)

이 기법들을 이용하면 완벽한 TDD(Test Driven Development) 가 가능해 집니다. 설계가, 구현이.. 안된 객체를 대상으로 계약된 인터페이스를 이용하여 Mock Object 를 생성하는 기법들입니다. Lightweight Framework이라고 설명하긴 하지만, Pex 등과 궁합이 잘 맞는 프레임워크이기도 합니다.

   

Object Class Recognition

http://research.microsoft.com/en-us/projects/ObjectClassRecognition/

이 기술은 이미지 처리 기술로, 물체를 인식하는 기술입니다. 헐~~ 왜 헐~이냐고요? 아마도 이 분야에 바로 기술을 적용하려면 Microsoft 역사상 선도 기술 업체를 인수해 버렸지만, 이번 기술은 그 기반부터 연구를 진행하는 프로젝트네요. 아마도 HD Viewer 등과 더불어 이미지 처리 기술의 노하우를 쌓으려는 작정인가 봅니다.

물론 이런 비슷한 기술은 이미 선도 업체에서 구현하였습니다만, Microsoft Research 에서 직접 연구하는 것은 참으로 반갑네요. 아마도 Microsoft 도 인터넷 서비스에 뛰어든 만큼 새로운 서비스와 모바일과 결합된 서비스가 나오리라 생각이 됩니다.

   

Qex - Symbolic SQL Query Exploration

http://research.microsoft.com/en-us/projects/qex/

Qex 는 Pex 의 SQL Query 버전인가 봅니다. Pex 는 코드 구분을 분석해서 자동적으로 테스트 파라미터 등을 선정하여 테스트를 진행하는데, Qex 는 그 대상이 SQL Query 인 것 같습니다. 정확한 산출물은 없지만, 이미 공개된 다른 파생 프로젝트에서 문서를 보시면 이해하시는데 도움이 될 것 같습니다.

   

Publications

   

Microsoft Research 를 둘러보세요^^

http://research.microsoft.com/en-us/default.aspx

Microsoft Research 에는 여러분의 상상력과 지적 호기심을 자극할 만한 많은 프로젝트가 진행 중입니다. 이미지 처리, Embedded, 과학, 공학 등등…

그리고 좋은 내용이 있으면 함께 공유 부탁 드립니다.

Welcome to Asynchronous C#(0) - C#의 전설.

C# 2010. 11. 5. 09:00 Posted by 알 수 없는 사용자

- C#엔 슬픈 전설이 있어...

C# 2.0을 만들던 사람들은 반복해서 실행하는 로직(iterator logic)을 짜기가 쵸낸 어렵다는 것을 깨달았습니다. 그래서 그들은 반복자를 추가했지요....

그리고 그들은 지역변수를 사용하는 작은 메서드를 짜는 게 쵸낸 귀찮다는 사실을 깨달았습니다. 그래서 그들은 익명 메서드를 추가했지요....

그리고 C# 3.0을 만들던 개발자들은 복잡한 데이터 집합에 대해 정렬, 필터링, 조인, 그룹핑, 합계내기가 정말 어렵다는 사실을 깨달았습니다. 그리고 그들은 쿼리 종합 선물세트와 기타 기능을 만들고 LINQ라고 이름을 붙였죠....

그리고 C# 4.0의 개발자들은 깨달았습니다. 현대적이거나 기존에 존재하는 동적 오브젝트 모델과 상호운용을 하는 것이 얼마나 어려운지 말이죠. 그래서 그들은 dynamic 타입을 추가했습니다....

그리고 C# 5.0의 개발자들은 비동기 호출을 사용하는 코드를 작성하는게 여러모로 얼마나 어려운 일인지 깨달았습니다....

- Eric Lippert의 포스팅에서 간단하게 추려서 제 맘대로 번역... 


- 하지만 난 전설따윈 믿지않아.

안녕하세요 :) 그동안 'Welcome to Dynamic C#'시리즈로 신나게 글을 양산했다가, 어느덧 지나간 세월에 깜짝놀라 다시 돌아온 워너비입니다. 신나게 놀다보니 세월 지나가는지를 모르겠더군요. 호호호호호 :) 어느덧 C#도 새로운 버전에 대한 이야기가 솔솔 기어나오고 있습니다!! 그 기어나오는 이야기를 잘 추려서 제 내공이 허락하는 수준에서 전달해드리고자 합니다.(강조에 주의)

강조해놓은 부분을 보시면, '아... 실력이 좀 되는 사람이면 이 친구 글에서는 얻을 게 없겠구나'하는 예감이 오실겁니다. 그리고 그동안 제가 하는 연재를 보신 분들은 '아... 이 친구 글은 심한 버퍼링을 뚫고 2-3개월에 한번씩 포풍 업데이트가 되겠구나'하는 예감도 오시겠죠.

Bingo~

B, I, N, G, O :)

그럼 언젠가 돌아오겠습니다. :)

Microsoft Research 프로젝트로 알아보는 새로운 세대의 시작

Microsoft Research 프로젝트는 Microsoft 에서 진행하는 오픈된 기술과 연구를 하는 R&D 조직으로, 새로운 비즈니스와 기술을 결합하는 프로젝트입니다. 최근 들어 Microsoft Research 사이트의 프로젝트는 작년과 비교해 엄청나게 늘어났습니다. 작년까지만 해도 불과 10~30개의 오픈된 프로젝트가 현재 수백 개의 프로젝트로 늘어난 것이 굉장히 놀랍니다. 그만큼 기술의 트랜드가 빠르게 변한다는 반증이 되겠지요.

Microsoft Research 프로젝트를 열람해 보는 것은 매우 중요합니다. 왜냐하면 당장 2~3년 내에 현실화되는 기술들도 있으며, 현재의 기술이 작년의 Microsoft Research 프로젝트와 통합된 것이 많기 때문이죠. 앞으로 나와는 상관 없는 것들도 있지만, 간접적으로 영향권에 들게 될거라고 생각합니다. 과연 스마트 폰이 어느샌가 내 호주머니 속에 들어가게 될지 모르는 것 처럼 말이죠^^

그럼 Microsoft Research 프로젝트에서 진행하고 있는 재미있는 프로젝트를 소개해 드립니다. 말씀 드렸다시피 이 프로젝트들은 언제 사라질지 모르는 것들이지만, 가치가 있는 것들은 모조리 비즈니스/웹/개발 영역에 접목이 될 수 있습니다.

   

Microsoft Research 진행 프로젝트 소개

A programming language for composable DNA circuits

http://research.microsoft.com/en-us/projects/dna/

이 프로젝트는 프로그래밍 언어의 핵심 로직을 시각화(Visualization)해 주는 프로젝트입니다. 가령 아래와 같은 로직이 있다고 치면, 참 답답하죠. 왜냐하면 제가 무슨 뜻인지 모르니까요^^

directive sample 20000.0 1000

directive plot <kkks t^ kkksr>; <kkppl t^ kkpp x^>; <kpp t^ kppr>;

<kkk t^ kkkr>; <kkl t^ kk x^>; <k t^ kr>; <kkpl t^ kkp x^>; <kp t^ kpr>

directive scale 10.0

def bind = 0.0003 (* /nM/s *)

def unbind = 0.1126 (* /s *)

def Init = 50

def Low = 1

def Excess = 100

   

new x@ bind,unbind

new t@ bind,unbind

   

def SpeciesL(N,al,a) = N * <al t^ a x^>

def SpeciesR(N,a,ar) = N * <a t^ ar>

def BinaryLRxLR(N,al,a,b,br,cl,c,d,dr) = (* A + B ->{N} C + D *)

new i

( constant N * t^*:[a x^ b]<i cl t^ i t^ dr>:t^*

| constant N * Excess * x^*:[b i]:[cl t^]<c x^>:[i]:<d>[t^ dr]

)

   

new e1l new e1 new kkk new kkkr new kkl new kk new k new kr

new e2l new e2 new kkpase new kkpaser new kpasel new kpase

new kkks new kkksr new kkpl new kkp new kkppl new kkpp

new kp new kpr new kpp new kppr

   

( SpeciesL(1,e1l,e1) (* E1 *)

| SpeciesR(10,kkk,kkkr) (* 10 KKK *)

| SpeciesL(100,kkl,kk) (* 100 KK *)

| SpeciesR(100,k,kr) (* 100 K *)

| SpeciesL(1,e2l,e2) (* E2 *)

| SpeciesR(1,kkpase,kkpaser) (* KKPase *)

| SpeciesL(1,kpasel,kpase) (* KPase *)

| BinaryLRxLR(Init,e1l,e1,kkk,kkkr,e1l,e1,kkks,kkksr) (* E1 + KKK ->{r} E1 + KKKs *)

| BinaryLRxLR(Low,e2l,e2,kkks,kkksr,e2l,e2,kkk,kkkr) (* E2 + KKKs ->{r} E2 + KKK *)

| BinaryLRxLR(Init,kkl,kk,kkks,kkksr,kkpl,kkp,kkks,kkksr) (* KK + KKKs ->{r} KKP + KKKs *)

| BinaryLRxLR(Init,kkpl,kkp,kkks,kkksr,kkppl,kkpp,kkks,kkksr) (* KKP + KKKs ->{r} KKPP + KKKs *)

| BinaryLRxLR(Low,kkppl,kkpp,kkpase,kkpaser,kkpl,kkp,kkpase,kkpaser) (* KKPP + KKPase ->{r} KKP + KKPase *)

| BinaryLRxLR(Low,kkpl,kkp,kkpase,kkpaser,kkl,kk,kkpase,kkpaser) (* KKP + KKPase ->{r} KK + KKPase *)

| BinaryLRxLR(Init,kkppl,kkpp,k,kr,kkppl,kkpp,kp,kpr) (* KKPP + K ->{r} KKPP + KP *)

| BinaryLRxLR(Init,kkppl,kkpp,kp,kpr,kkppl,kkpp,kpp,kppr) (* KKPP + KP ->{r} KKPP + KPP *)

| BinaryLRxLR(Low,kpasel,kpase,kpp,kppr,kpasel,kpase,kp,kpr) (* KPase + KPP ->{r} KPase + KP *)

| BinaryLRxLR(Low,kpasel,kpase,kp,kpr,kpasel,kpase,k,kr) (* KPase + KP ->{r} KPase + K *)

)

어찌되었건 이런 코드는 다양한 방법으로 시각화를 해줍니다. 아래는 제가 시뮬레이션해 보니 이런 결과가 나오네요.

중요한 것은 이런 형태의 시각화(Visualization)은 지속적으로 발전하고 있습니다. 모델링(Modeling) 과 DSL(Domain Specifically Language) 의 중요성과 함께 지속적으로 발전하게 될 테니까요.

이 데모는 실버라이트로 작성되어 웹에서 직접 테스트해 보실 수 있습니다. http://lepton.research.microsoft.com/webdna/

   

   

Ajax View

http://research.microsoft.com/en-us/projects/ajaxview/

AJAX 기술로 직격타를 받고 성장한 것이 바로 Web 2.0 입니다. 그리고 Web 2.0을 넘어 Web 3.0이 언급이 되었고, 더 나아가 SNS(소셜 네트워크 서비스)로 발전한 가운데, 가장 영향력을 미친 기술이 AJAX 입니다. 기술적으로 트래픽의 라운드 트립을 줄이고, 분산 아키텍처에 지대한 영향을 미쳤으며, 더 나아가 브라우징(Browsing) 사용성을 극대화한 기술입니다.

하지만 사실상, AJAX 기술은 불필요한 라운드 트립을 증가시킬 수 있는 가장 적절한 수단이기 때문에 잘 사용하는 것이 어려운 기술이기도 합니다. Ajax(Asynchronous JavaScript and XML) 는 순수한 자바스크립트 기술로써 많은 부분을 클라이언트에 의존하지만 자바스크립트와 더불어 HTML CodeDom, XML, DHTML 까지 확장되어 그 영역이 상당하게 복합된 기술이라고 보셔도 됩니다.

   

그렇다면 과연 AJAX 를 어떻게 잘 쓸 것인가에 대한 고민을 이 Ajax View 프로젝트가 도움을 줄 것 같습니다. 이 기술을 중심으로 파생되어 AJAX Performance Profiling, Monitoring 기술의 기반이 되는 것 같습니다. 자세한 내용은 위의 사이트 링크를 참고하세요.

   

Automated Test Generation (ATG)

일찍이 Microsoft 는 1990년대 이후부터 테스팅 기술에 대한 연구를 꾸준히 해온 정통 소프트웨어 기업입니다. 코드 레벨의 테스트는 물론이며, Windows 95 시절에 지원되기 시작한 Plug-and-Plug(하드웨어를 꽂으면 인식하는 기술) 등 상상하지도 못했던 많은 기능을 자동화 테스팅한 기업이기도 합니다. 지금 우리 세대에서 맛보고 있는 테스팅 기술은 Microsoft 의 실제 내부의 기술과는 매우 격차가 있지요. (인정합니다.^^;)

처음 공식적으로 나온 White Box Automation Test 도구인 PEX 가 Visual Studio 2008 시절부터 나오긴 하였지만, 완성된 기술은 아니며 계속 발전하는 기술입니다. PEX 와 관련하여 온라인 세미나를 찍은 것이 있는데 못찾겠군요.;; 대신 아래의 테스팅과 관련된 내용을 참고 하세요.

[ALM-Test] 6. Load Runner vs Visual Studio 2010 테스팅 비교 분석 - http://willstory.tistory.com/4 제공
[ALM-Test] 5. 테스트 계획
[ALM-Test] 4. 테스터(SDET) 의 역할
[ALM-Test] 3. 테스터에 대한 오해와 진실
[ALM-Test] 2. 왜 단위 테스트를 해야 하는가? [2]
[ALM-Test] 1. 왜 단위 테스트를 해야 하는가? [1]
[Testing] Moq.NET (T/B Driven Development)
[Testing] BDD (Behavior-Driven Development–행위 주도 개발)
[Testing] TDD (Test-Driven Development-테스트 주도 개발)

아무튼 이런 테스팅을 위해서 Dynamic Proxy 기술과 Dynamic MSIL Injection 같은 기술이 필요한데, 이미 이런 부류의 닷넷 기술이 존재하긴 합니다. 그 중에 대표적인 것이 Microsoft.CCI 와 Code Contract, Castle Dynamic Proxy, Mono Cecil, Moles 등등등…

하지만 이번 이 프로젝트는 이 기반 기술 들을 통합하려는 의지를 보이는 것 같습니다. 개인적으로 굉장히 기대를 하고 있는 프로젝트이기도 합니다.

   

Code Contracts

http://research.microsoft.com/en-us/projects/contracts/

Code Contracts 는 이미 유명한 기술입니다. 초기에 Microsoft Research 프로젝트로 진행 중이다가 Visual Studio 2008 시절에 릴리즈가 되었으며, .NET Framework 4.0 와 Visual Studio 2010 에는 아예 탑재 시켜버렸습니다. Code Contract 를 직역하면 코드 계약(Code Contract) 인데, 코드간의 명확한 명세를 코드 레벨에서 작성하는 것입니다. 이것도 예전에 온라인 세미나를 했었는데 못찾겠군요;;

명확한 코드 계약이 왜 필요하냐…? 라고 물으신다면 당시 세미나에서 예시를 든 것이, "당신이 회사를 다닌다면 회사와 계약을 합니다. 계약서에는 연봉 정보도 있고, 근태 규칙도 있고 여러 가지가 있습니다..." 마찬가지로 내가 만든 코드를 누군가 써야 할 때 바로 그 명세가 되는 것이 Code Contract 입니다.

이 기술로 파생될 수 있는 기술은 상당히 많습니다. 명확하게 코드를 계약하게 되면 테스트에 굉장히 용이하며, 더 나아가 자동화 테스트(PEX 와 같은)에서 훨씬 여유로워 집니다. 그리고 정적 분석(Static Analytics) 기술과 접목하여 잠재적인 코드의 계약 관계를 파악하여 미리 경고나 오류를 발생해 줄 수 도 있고요.

하지만 저의 경우는 그리 톡톡히 효과를 보지는 못했습니다. 왜냐하면 명확한 계약은 1:1 계약에서 효과가 있지만, 1:N, N:N 간의 계약에서는 그 계약 조건이 명확해 질 수가 없습니다. 현재 나온 PEX 기술과 Code Contract 를 조합하여 계약을 파생시키는 기술적인 부분이 부족하며, 계약의 제약 조건 등 아직은 적극적으로 사용하기에는 부족해 보입니다.

하지만 이 기술을 근간으로 하여 더 효과적인 많은 방법들이 위의 Automated Test Generation (ATG) 프로젝트 등으로 활발히 연구 중이며, 앞으로도 지속적으로 관심을 가질 기술은 분명합니다.

   

Composable Virtual Earth

http://research.microsoft.com/en-us/projects/cve/

제가 설명드릴 만큼 깊이 이해를 못하고 있기 때문에, 참고하세요^^; 중요한 것은 이미지 프로세싱 등의 기술로 효과적으로 운용을 하고자 하는 것 같습니다.

   

DryadLINQ

http://research.microsoft.com/en-us/projects/dryadlinq/

이 프로젝트는 C#의 LINQ+Parallel 기술을 접목하여 분산된 데이터의 접근성을 극대화한 기술입니다. 이미 잘 알고 있는 LINQ 와 .NET 4.0부터 제공되는 TPL(Task Parallel Library)를 이용하여 단순한 분산 데이터에 접근하는 방법입니다. 기존의 LINQ to SQL, Entity Framework 과 같이 단일 데이터 소스가 아닌 클러스터링 된 분산 데이터에 대상이 됩니다.

이 프로젝트는 기존에 존재하는 기술을 접목하여 새로운 기술의 탄생의 근원이기도 합니다. 하지만 생각해보면 분산된, 클러스터링된 데이터를 왜 DryadLINQ 를 써야 할까. 그만큼 대규모의 데이터면 '데이터베이스 관리자를 따로 둘텐데' 말이죠.

제 짧은 소견으로는 분명히 이 기술은 Microsoft Cloud 기술인 Azure 에 접목될 가능성이 농후합니다. 즉, Azure 기반의 클라우드 기술을 엔터프라이즈(Enterprise) 급으로 끌어올릴 수 있는 전략적인 기술이기도 합니다. 이런 부분에서 아직 Azure 는 완성된 기술은 아닙니다. 계속 발전하는 기술이지…

   

Doloto

http://research.microsoft.com/en-us/projects/doloto/

이 프로젝트는 정말인지 기대가 됩니다. 아까 말씀 드린 'Ajax View' 프로젝트와 연관이 있어 보이지만, 이 프로젝트는 나름대로 효과를 톡톡히 보여줄 것 같습니다.

문제는 Web 2.0 은 말씀 드린대로 AJAX 기술과 떨어질 수 없는 관계이기도 합니다. 그런데 데이터 처리를 서버&클라이언트로 분산하면서 결국은 서버를 거치게 되고, 원치않던 라운드 트립은 증가하게 되고, 결국은 사용자의 사용성(광범위한…)은 저하될 수 있습니다. 뭐가 문제일까요? AJAX 가 문제일까, Web 2.0 이 문제일까, 코드가 문제일까, 시스템이 문제일까….

Doloto 는 과분하게도 이런 문제를 큰 고민 없이 해결해 줍니다. 아래는 그래프는 Doloto 를 적용하면 대략 50%에 근사하게 성능이 개선되는 수치입니다. 성능을 개선하기 위해 특별히 코드를 변경할 필요도 없다고 합니다. 그렇다면 연관된 기술은 서버 코드/클라이언트 코드 분석 기술 이외에 캐싱(Caching) 일 텐데…

일단 기대가 됩니다.

   

ExtendedReflection - Dynamic Analysis Framework for .NET

http://research.microsoft.com/en-us/projects/extendedreflection/

이 기술은 'Automated Test Generation (ATG)' 과 없지 않아 연관이 될 수 있을 것 같습니다. 여기에서는 분석 도구라고 설명하지만, 이런 Low-Level의 구현이 가장 잘 되어 있는 프레임워크는 Mono.Cecil입니다. 그러고 보면 약간은 중복성이 있어 보이는 프로젝트이기도 합니다.

적어도 Microsoft.CCI 는 그렇다쳐도 Microsoft.Unity.ObjectBuilder, Castle.DynamicProxy와 Mono.Cecil은 .NET 오픈 소스 중에 가장 대표적인 Dynamic Proxy 및 MSIL 기술인데, 어찌될지 그냥 지켜보고 있습니다.

단순히 기존 존재하는 오픈 소스 대체용도인지, 다양한 기술을 접목하고자 하는 진정한 프레임워크 기반 기술인지는 두고 볼 일입니다.

   

F#

http://research.microsoft.com/en-us/projects/fsharpproj/

깜놀하셨죠? 바로 F# 도 Microsoft Research 에서 태생한 언어입니다. 그냥 그렇다구요^^

   

Graphical tools for text analysis

특별히 아래의 그림만으로 이해하시리라 믿고, 패스!

   

HD View

예전에 Silverlight 의 딥줌(DeepZoom) 을 기억하십니까? 저는 사실 결과물에 대해 다른 것은 없지만, 뭔가 이미지 프로세싱 측면에서 다른 접근 방식을 가지고 가는 것 같습니다. 워낙 자료도 적어서 뭐라고 설명 드리기는 힘들 것 같아요.

다만, 아래의 그림을 보시면 딥줌과 유사하지만, 그래도 유사할 것 같아요^^… 어떤 알고리즘인지가 궁금할 뿐;;

   

HD View SL

위의 'HD View' 의 실버라이트 버전입니다. 참고^^

   

   

정리

Microsoft 는 소프트웨어 개발 기업으로 세계에서 1위 기업입니다. 그 중, Microsoft Research 프로젝트는 여러분들에게 오픈된 프로젝트일 뿐이며, 내부적으로 더 많은 연구가 계속되고 있습니다. 예를 들어, http://codeplex.com 은 여러분들에게 공개된 오픈 소스 커뮤니티지만, Microsoft 내부에는 더 많은 프로젝트들이 수백 개씩 오픈 되어 있습니다. (제가 어떻게 아냐구요? Microsoft 직원이 쓴 책에 그렇다고 말하더군요^^)

다만, 그 중에서 저희에게 오픈된 기술 R&D 영역이 Microsoft Research 프로젝트입니다. 그리고 관심이 없으셔도 상관은 없답니다. 최근 기술 트랜드는 너무나도 빨리 나오고, 변하기 때문에 모두 따라가기가 벅차기도 합니다. 그리고 이 모든 것을 자세하게 알 수 없게 되었습니다. 중요한 것은 내가, 여러분들이 받아들일 기술/트랜드를 준비할 수 있겠지요. 모르고 아는 것과 알고 아는 것은 상당히 다릅니다.

직접적으로 이런 기술들이 나에게는 관련이 없지만, Microsoft 는 비즈니스/웹/시각화/클라우드에 지속적으로 시도를 하는 것을 알 수 있으며, 장차 알게 모르게 도움이 될 거라고 믿습니다. 그리고 이 서비스/기술을 이용하는 사람은 여러분들이 될 수도….^^