약 3개월만의 작업 기록 포스팅입니다. Core Runtime에 대한 테스트를 강화하고 코딩할 때 불편한 부분을 최소화하면서 실제 C 프로그래밍 언어와 비슷한 환경을 나타낼 수 있도록 만드는데에 많은 노력을 들였습니다.

Buffer, String 계열 클래스의 확장 및 개선

        [Test]
        public void memchrTest()
        {
            int ch = 'r';
            GlobalHeapAnsiString str = new GlobalHeapAnsiString("lazy");
            GlobalHeapAnsiString @string = new GlobalHeapAnsiString("The quick brown dog jumps over the lazy fox");
            GlobalHeapAnsiString fmt1 = new GlobalHeapAnsiString("         1         2         3         4         5");
            GlobalHeapAnsiString fmt2 = new GlobalHeapAnsiString("12345678901234567890123456789012345678901234567890");

            SBytePointer pdest;
            int result;

            Console.Write("String to be searched:\n             {0}\n", @string.ToString());
            Console.Write("             {0}\n             {1}\n\n", fmt1.ToString(), fmt2.ToString());

            Console.Write("Search char: {0}\n", (char)ch);
            pdest = msvcrt.memchr(@string, ch, (size_t)@string.Length);
            result = (int)(pdest - @string + 1);

            if (pdest != null)
                Console.Write("Result:      {0} found at position {1}\n", (char)ch, result);
            else
                Console.Write("Result:      {0} not found\n", (char)ch);

            Assert.AreEqual(12, result);

            str.Dispose();
            @string.Dispose();
            fmt1.Dispose();
            fmt2.Dispose();
        }

위의 코드에서 보시는것처럼 String Buffer 클래스에 직접 Add / Subtract 연산자 오버로드를 추가하여 실제 포인터 연산의 결과를 재현합니다. 형식화된 Pointer 클래스와 다른점이 있다면 자기 자신에 대한 주소 설정은 허용하지 않습니다. 이것은 비관리 메모리 영역의 주소가 변경됨으로 인하여 발생할 수 있는 할당 해지 실패로 인한 메모리 누수를 예방하기 위한 디자인입니다.

총 20여종의 주요 값 형식에 대한 형식화된 포인터 제공 (Typed Pointer)

형식화된 포인터에 세부적인 기능 조절을 더하고 제거하는 노력을 통하여 총 20여종의 주요 값 형식에 대한 형식화된 포인터를 제공하게 되었습니다. 이들 포인터 형식 모두는 외관상 CLS 표준 사양을 만족하도록 만들어졌으며 포인터 개념이 없는 프로그래밍 언어 (예: Visual Basic .NET, Visual J# 등)에서도 포인터 연산을 간접적으로 사용할 수 있게 디자인되어있습니다.

  • AutoCharPointer
  • BooleanPointer
  • BytePointer
  • DateTimePointer
  • DecimalPointer
  • DoublePointer
  • GuidPointer
  • Int16Pointer
  • Int32Pointer
  • Int64Pointer
  • IntPtrPointer
  • Pointer<T>
  • SBytePointer
  • SinglePointer
  • TimeSpanPointer
  • UInt16Pointer
  • UInt32Pointer
  • UInt64Pointer
  • UIntPtrPointer
  • WideCharPointer

사용 빈도가 높을 것으로 추정되거나 기본 형식들에 대한 형식화된 포인터는 모두 제공하고 있습니다. 하지만 특정한 목적으로 직접 추가한 구조체에 대한 지원도 필요했고 경우에 따라서는 제네릭에 대응되는 가변 포인터에 대한 구현을 필요로 하였기 때문에 Pointer<T> 형식을 새로 추가하였습니다. 전용 포인터를 이용하여 계산하는것보다는 연산 횟수가 많다는것이 단점입니다.

실제 메모리 구조의 크기를 조사해주는 unsafe sizeof() 연산자의 Managed 버전 제공

        [Test]
        public void NativeSizeOfTest1()
        {
            foreach (Type eachType in new Type[] { typeof(char), typeof(bool),
                typeof(byte), typeof(DateTime), typeof(decimal), typeof(double),
                typeof(Guid), typeof(short), typeof(int), typeof(long), typeof(IntPtr),
                typeof(sbyte), typeof(float), typeof(TimeSpan), typeof(ushort),
                typeof(uint), typeof(ulong), typeof(UIntPtr)})
            {
                Console.WriteLine(">> {0} byte{1}", Utilities.NativeSizeOf(eachType),
                    Utilities.NativeSizeOf(eachType) > 1 ? "s" : String.Empty);
            }
        }

위의 테스트 코드에서 나열한 형식들에 대한 sizeof 연산자의 결과를 반환해주는것이 NativeSizeOf 메서드입니다. 그 외의 형식들에 대해서는 Marshal.SizeOf의 결과를 반환합니다.

NUnit 테스트 코드 프로젝트 시작

프로젝트에 대한 검증을 수행하기 위하여 NUnit 프로젝트를 생성하고 테스트하면서 조금씩 진척을 시켜나가고 있습니다. NUnit 테스트 코드의 내용은 실제 적용에 많은 도움이 되는 예제 코드로도 활용이 가능하니 한번 살펴보시길 권합니다.

향후 계획

조만간 공식 릴리즈를 0.1 버전으로 런칭할 계획을 세우고 있습니다. 그리고 준비가 되는대로 Windows CE, Windows Mobile에 관한 API도 수집하여 데이터베이스화를 수행할 예정이니 관심있으신 분들은 블로그나 데브피아 등을 통하여 연락주시면 언제든 채널이 열려있으니 함께 하실 수 있습니다.

프로젝트 홈페이지는 http://blendxplatform.codeplex.com 이며 누구나 체크아웃해가실 수 있습니다. 서브 버전, TFS 등을 이용하여 쉽게 받아가실 수 있습니다.

Subversion 주소: https://blendxplatform.svn.codeplex.com/svn
TFS 주소: https://tfs05.codeplex.com

 

 

크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)

닷넷 프레임워크 기술들 중 가장 적게 알려지고 그 비중이 많이 축소되어 소개되는 부문이 바로 Visual C++ CLR일 것입니다. 생각보다 C++ CLR이 유용할 수 있음에도 불구하고 여론에 떠밀려서 거의 사장되다시피하고 있지요. 이번 블로그 포스트에서는 C++ CLR을 통해서 실용적인 코딩 하나를 해볼까합니다.

C++과 더불어 관련 라이브러리들 (STL, ATL, WTL, Boost, MFC 등)의 경우 일반적인 응용프로그램을 작성하거나, 성능 튜닝이 필요한 응용프로그램들을 작성하거나, 수학 라이브러리 등의 힘을 빌어 불필요한 오버헤드가 없는 고속 연산을 처리하는 등의 목적에 알맞게 디자인되어있습니다. 그러나 엔터프라이즈 프로그래밍의 경우에서처럼 구조화된 처리를 수행해야 하는 경우 상당히 불편한 점이 많습니다. 간단한 예로 당장 XML 문서 하나 분석하는 것도 썩 편리하지는 않지요.

Visual Studio 패밀리에서 공식적으로 제공되는 기능은 아니지만 C++ CLR도 닷넷 프레임워크 위에서 기동되는 어셈블리를 작성할 수 있습니다. 그리고 더 중요한 것은 기존의 x86 코드나 x64 코드를 MSIL 어셈블리 사이에 끼워넣을 수 있다는 점입니다. 이러한 사실을 바탕으로 하여 하이브리드 코드를 만들 수 있습니다.

그럼 하나씩 살펴보도록 하겠습니다.

1. C++ CLR 기반의 클래스 라이브러리 프로젝트 하나를 만듭니다. 프로젝트 이름으로 여기서는 "CLRxASPX"를 사용하기로 하겠습니다.

2. 여느 닷넷 프로젝트처럼 예상 가능한 종류의 파일들이 만들어집니다. AssemblyInfo.cpp 파일은 어셈블리 어트리뷰트를 정의하는 부분으로 다음과 같이 코드가 구성되어있습니다.

AssemblyInfo.cpp 보기

C#에서와 마찬가지인 어트리뷰트 사용법입니다. 다만 C++ 컴파일러의 특성상 空문장임을 뒷쪽에 명시해둔 것이 다른 부분이라고 할 수 있겠습니다. 그리고 네임스페이스의 참조 방법이 C#과 동일하게 되어있습니다. C#에서 흔히 사용하는 using은 C++의 using namespace와 같습니다. 그리고 C++에서 흔히 사용하는 using std::cout; 같은 참조는 C#에서는 using Console = System.Console; 과 같이 표현이 가능합니다.

특이한 점이 하나 더 있다면 stdafx.h의 존재입니다. MFC나 ATL 프로젝트에서 Precompiled Header라는 명목으로 많이 사용되던 것이 C++ CLR에도 그대로 적용된 걸 볼 수 있습니다. 거리낌없이 그 개념 그대로 stdafx.h에 Windows API 헤더를 추가하거나 프로젝트 전반에 걸쳐 사용하고 싶은 다른 라이브러리의 헤더를 추가하면 됩니다.

그럼 stdafx.h는 어떻게 구성되어있는지 한 번 살펴보도록 하겠습니다.

stdafx.h 보기

C++ CLR의 유용함이 느껴지는 부분입니다. 굵게 표시한 부분이 예제를 위하여 추가된 코드로, Win32 API 헤더를 추가한 것입니다. WIN32_LEAN_AND_MEAN은 컴파일러나 링커의 처리를 최소화하기 위한 것으로 통계적으로 사용 확률이 그닥 높지 않은 코드, 라이브러리를 사전에 제거해주는 옵션입니다. 예제에서는 API 참조를 위해서만 stdafx.h를 이용한 것이므로 stdafx.cpp에는 다른 서술이 되어있지 않아서 생략합니다.

이제 실제 코드를 살펴보기로 합니다.

CLRxASPX.h 보기

using namespace로 모든 네임스페이스의 요소들을 참조할 수도 있지만  필요한 항목들만 위와 같이 참조할 수도 있습니다. 그리고 아래의 클래스 선언을 보면 일반 C++ 클래스 선언과는 구별되는 내용들이 몇 가지 있습니다. 우선, class 키워드 앞에 ref 키워드가 사용된 걸 볼 수 있는데 이것이 이 클래스가 Managed Class 임을 나타내는 것입니다. 그 다음에는 상속 대상을 ASP.NET의 페이지 클래스로 정한 것이 보입니다.

Protected 멤버 메서드로 Page_Load 메서드가 선언된 것이 보입니다. 이 때 알아둘 것이 있는데 ASP.NET은 내부적으로 Reflection을 통해서 실제로 Page 클래스의 Load 이벤트에 추가한 이벤트 처리기가 아니라도 자동으로 이름을 통하여 호출 대상을 결정하기 때문에 위의 메서드는 항상 실행됩니다.

그리고 C++ CLR에서 닷넷 프레임워크의 형식들을 이용할 때에는 닷넷 프레임워크 상의 관리되는 참조 객체임을 표현하기 위하여 과거의 Managed Extensions for C++ 시절때 사용하였던 __gc * 형식 대신 ^ 기호를 사용합니다. 포인터의 * 와는 구분되는 것으로 주소값을 얻기 위한 형변환 시도는 허용되지 않습니다. 이렇게 사용되는 형변환은 주소값에 대한 형변환이 아니라 형식 자체에 대한 형변환 시도가 됩니다. 별도로 해당 형식이 암묵적/명시적 형변환 연산자를 가지고 있지 않을 경우 상속 관계와는 무관하므로 컴파일이 실패합니다. 참고로, Page_Load 메서드가 이벤트 핸들러로서의 조건을 충족하려면 반환 형식은 void, 즉 반환 대상이 없으며, 두 개의 매개 변수를 받아들여야 합니다. 하나는 이벤트를 발행한 출처의 참조, 또 하나는 이벤트 인자 개체의 참조입니다. 자세한 내용은 System::EventHandler 대리자를 참고하시면 됩니다.

CLRxASPX.cpp 보기

구현하기 나름이지만, 원래의 C++ 코드 스타일을 유지하기 위하여 선언부와 구현부를 나눈다면 위와 같은 형태로 cpp 파일에 메서드 본문을 작성할 수 있습니다. 이 때, 메서드의 시그니처에 전체 네임스페이스가 지정되어야 함을 유의합니다.

windows.h 헤더 파일 내에 포함되어있는 항목들 중 시스템 정보를 추출하는 API를 이용해보기로 합니다. 이 부분은 C#이나 기타 닷넷 환경에서는 원래 Platform Invoke를 통하여 우회적으로 마샬링해야 하는 부분이지만 C++ CLR의 특성에 따라 Native Code를 평소처럼 실행할 수 있다는 것을 보여줍니다. SYSTEM_INFO 구조체의 주소값을 전달하여 시스템 정보를 구조체에 채우도록 만들고 이를 ASP.NET 서비스에서 보여준다는 것이 예제 프로그램의 컨셉입니다.

Label 컨트롤을 생성하기 위하여 gcnew 연산자를 사용하였습니다. 역시 C++에서 원래 사용하던 new 연산자와 구분되는 것입니다. gcnew 연산자로 관리되는 객체를 만들고, Text 프로퍼티에 문자열을 지정하였습니다. 관리 객체에 지정되는 문자열은 자동으로 System::String의 인스턴스로 분류되어 처리되도록 만들어져 있기 때문에 유니코드 문장임을 나타내는 접두사 L 없이도 쓰일 수 있습니다. 또한, 아랫쪽 코드를 보면 System::String 형식에만 정의되어있는 문자열간 합치기 기능이 C++에서도 동작하는 것을 볼 수 있습니다.

위의 예제 코드를 작성한 다음, 결과를 확인하기 위하여 아래와 같이 IIS 7.0에서 사용할 수 있는 web.config 파일을 작성하여 웹 어플리케이션 디렉터리를 구축하고, 해당 웹 어플리케이션 디렉터리 바로 아래의 Bin 폴더에 이 프로젝트로 빌드한 DLL을 저장하였습니다.

web.config 보기

위의 내용에서 확인해야 할 부분이 두 가지가 있습니다. IIS 7의 system.webServer 섹션은 닷넷 프레임워크가 처리하는 것이 아니라 IIS 7이 스스로 처리하는 부분입니다. 우선 핸들러에 type이라고 되어있는 부분은 닷넷 프레임워크에서 불러들일 IHttpHandler 인터페이스와 호환되는 형식의 약식 명칭을 지정하는 부분입니다. Page 클래스를 상속함으로서 이 부분이 자동으로 구현되었기 때문에 우리가 방금 작성한 C++ CLR 클래스의 약식 명칭을 여기에 기술합니다. 네임스페이스와 클래스 이름, 그리고 Bin 폴더 내에 들어있는 클래스 라이브러리의 어셈블리 이름을 여기에 기출합니다. 그리고 preCondition에서는 이 핸들러가 통합 모드에서 실행되어야 하고 닷넷 프레임워크 2.0 런타임을 사용하여 구동되어야 함을 표기하고 있습니다.

이제 실행 결과를 살펴보도록 하겠습니다.

C++ CLR이 Native Code와 잘 연동되어 ASP.NET 서비스를 수행하고 있는 것을 볼 수 있습니다. 여기서는 공식적으로 프로젝트 템플릿이 제공된 것이 아니라서 이와 같이 간소한 형태로만 프로그램을 작성하였지만 C++ CLR로도 이와 같이 프로그램 작성을 할 수 있다는 것을 확인할 수 있었습니다. Platform Invoke로 해결하기 어려운 문제는 이와 같이 프로그램의 형태에 제한을 갖지 않고 직접 C++의 힘을 빌릴 수도 있다는 것을 기억하면 쉽게 문제를 풀어나갈 수 있을 것입니다.

참고로 C++/CLI의 ECMA 표준안 문서는 http://www.ecma-international.org/publications/standards/Ecma-372.htm 에서 확인가능합니다.

크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)

예제로 올려진 확장자가 linq인 파일은 LINQPAD에서 열고 테스트할 수 있는 파일들입니다. LINQPAD는 http://www.linqpad.net/ 에서 다운로드 가능합니다.

크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)

그간 데브피아 C# 포럼 RSS 방송국을 통해서 보실 수 있었던 여러 포스트들을 과연 어떤 분들이 올려주셨는지 오늘은 특별히 이를 소개하는 포스트를 띄웁니다. 여러분께서도 여기에 참여하실 수 있습니다. :-)

한국 Microsoft 에반젤리스트 블로그 (http://blogs.msdn.com/eva/) : 에반젤리스트로 활동하시는 한국 Microsoft 관계자 여러분들의 최신 기술 동향 정보를 접할 수 있는 블로그입니다. 데브피아 RSS 방송국이 아니더라도 이 블로그는 최신 Microsoft 기술에 관하여 관심있으신 분들이라면 꼭 챙겨볼 필요가 있을 것입니다. :-)

MSDN 팝콘 블로그 (http://blogs.msdn.com/popcon) : 물론 에반젤리스트 블로그의 자료들은 훌륭합니다. 그러나, 에반젤리스트 블로그에서 미처 다루어지지 못했던 한국 Microsoft의 이모저모를 살펴볼 수 있는 또 다른 블로그가 바로 MSDN 팝콘 블로그입니다. 대학생 여러분들께서 누구나 관심있어 하실 전 세계적인 컴퓨터 관련 경진 대회인 Imagine Cup의 실황, Microsoft Student Partners 관련 모집 공고, 최신 제품들 (예: Internet Explorer 8)의 비디오 캐스트 동영상, 그리고 요즈음 큰 세미나들을 통해서 자주 접하실 수 있는 "Winkey와 꼬알라의 Windows 7 만담"까지 재미있는 컨텐츠들이 많습니다. :-)

mvpmagazine.net (http://www.mvpmagazine.net) : ASP 3.0 시절부터 지속적으로 ASP, ASP.NET에 관한 전문 도서를 저술하거나 외국 서적들을 번역 출간해오셨던 장현희 MVP님께서 운영하시는 블로그입니다. ASP.NET에 관한 최신 기술 동향을 살펴보고 싶으시다면 꼭 참고해야 할 블로그입니다. 참고로, 그간 집필하셨던 도서들도 살펴보시어 필요하신 책을 장만하실 것을 강력히 추천합니다. :-) http://www.aladdin.co.kr/search/wsearchresult.aspx?AuthorSearch=%c0%e5%c7%f6%c8%f1@83203&BranchType=1

Small Box (http://zmeun.tistory.com) : 생각하는 C#, LINQ를 출간하셨고, 다방면의 닷넷 프로그래밍 기술을 전문적으로 블로그에 강좌를 올려주시는 천호민 MVP님께서 운영하시는 블로그입니다. 최근 기술에 대한 동향을 살펴보기 위함이라면 역시 놓치지 말아야 할 블로그입니다. :-)

UMC BLOG (http://blog.powerumc.kr) : Visual Studio 2010 팀 스터디를 진행하시면서 올 연말에 출시될 Visual Studio 2010 및 .NET Framework 4.0에 대한 정보를 다양한 채널을 통하여 바쁘게 알려주시는 엄준일 MVP님의 블로그입니다. 데브피아 C# 포럼 마을에도 Visual Studio 2005/2008에 대한 전문적인 강좌를 올려주시는 고마운 분입니다. 참고로 팀 스터디 블로그는 "Visual Studio Team System 2010 공식 팀 블로그" 이며 주소는 http://vsts2010.net 입니다. :-)

ZZANGMYON BLOG♡ (http://www.zzangmyon.com) : Microsoft Expression MVP이며, 훈스닷넷에서 Expression 시삽을 맡고 계시는 장미연 MVP 님의 블로그입니다. Expression, Windows Presentation Foundation (WPF), Silverlight에 대한 다양한 정보를 제공하는 블로그입니다. 훈스닷넷 Expression/WPF/Silverlight 스터디, 세미나에 함께하신다면 더욱 좋겠죠? :-)

서진호의 윈도우 7 이야기 (http://windows7.textcube.com) : Windows Mobile, Windows Embedded, Windows 7 등 최신 Windows 운영 체제들에 관한 소식을 재빠르게 전해주시는 한국 Microsoft의 서진호 차장님의 Windows 7 블로그입니다. Windows 7 만담과 함께 둘러보시면 좋은 정보들을 많이 가지고 가실 수 있을 것입니다. :-)

데브피아 RSS 방송국은 이와 같이 닷넷 기술 및 UX 기술의 필두에 서 계신 분들의 블로그를 재빠르게 전달해 드리고 있습니다. 데브피아 RSS 방속국의 피드를 구독하시려면 아래의 링크를 클릭하시면 됩니다. :-)

RSS 피드 주소: http://feeds2.feedburner.com/devpia-csharp-rss
메일로 받아보기: http://feedburner.google.com/fb/a/mailverify?uri=devpia-csharp-rss

데브피아 C# 포럼 RSS 방송국에 블로그를 등록하고자 하시는 분들도 언제든 환영합니다. 데브피아 ID rkttu2002로 블로그 RSS 피드 주소와 함께 간단한 소개를 적어주시면 검토 후 등록하도록 하겠습니다. 감사합니다. :-)

크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Windows Azure MVP 남정현 (rkttu.com)