Project Blend: xPlatform을 조금씩 차곡차곡 진행시켜 나가고 있는 중입니다. 그동안 다양한 방법으로 조사하고 코드를 테스트하고 디자인한 결과를 드디어 조금씩 실행에 옮기고 있습니다.
포인터에 관한 새로운 접근
using System; using xPlatform; using xPlatform.Strings; using xPlatform.x86.msvcrt; namespace xPlatform.Core.Test { class Program { [STAThread] static void Main(string[] args) { const string targetString = "안녕하세요."; using (GlobalHeapAnsiString str = new GlobalHeapAnsiString(targetString)) { size_t len = msvcrt.strlen(str.Address); Console.WriteLine("String: \"{0}\", ANSI Length: {1}", targetString, len); BytePointer ptr = new BytePointer(str.Address); for (size_t i = (size_t)0u; i < len; i++, ptr++) Console.Write("{0} ", ptr.GetData().ToString()); } Console.WriteLine(); Console.WriteLine(); using (GlobalHeapUnicodeString str = new GlobalHeapUnicodeString(targetString)) { size_t len = msvcrt.wcslen(str.Address); Console.WriteLine("String: \"{0}\", Unicode Length: {1}", targetString, len); WideCharPointer ptr = new WideCharPointer(str.Address); for (size_t i = (size_t)0u; i < len; i++) Console.Write("{0} ", (ptr + (int)i).GetData().ToString()); } Console.WriteLine(); Console.ReadLine(); } } }
기존에 Base Class Library만을 이용하여 포인터를 활용해서 프로그래밍하는 작업은 작성해야 하는 코드의 양도 많았고 실수하기도 쉬웠습니다. 이러한 단점을 보완하고 좀 더 실용적이고 직관적으로 포인터 프로그래밍을 수행할 수 있는 방법을 고심한 끝에 위와 같은 패턴의 코드를 구현하였습니다.
GlobalHeapAnsiString, GlobalHeapUnicodeString 등의 클래스
보통 닷넷의 문자열을 비관리 메모리 영역에 저장하기 위해서 Marshal 클래스의 StringToHGlobalAnsi 같은 메서드를 이용해서 처리하는 것이 보편적이었습니다. 그리고 FreeHGlobal 메서드로 해당 메모리 블럭을 소거해야 하는 일도 잊지 않아야 했습니다. 이러한 작업을 자동화하기 위하여 위와 같은 클래스를 디자인하였습니다. 권한에 관한 이슈를 해결하지 못하여 SafeHandle 기반의 상속 혜택을 구현하지는 못하고 있습니다만 곧 해결할 수 있을것으로 기대합니다. Dispose 메서드를 노출하지는 않고 있으나 IDisposable 인터페이스를 구현하도록 하였습니다.
BytePointer, WideCharPointer 등의 클래스
Base Class Library가 제공하는 IntPtr이나 UIntPtr은 C/C++의 void*나 LPVOID에 가까운 것입니다. 형식 정보가 없기 때문에 주소 탐색 기능을 이용할 수 없다는 한계가 존재하기 때문에 이를 보완하기 위하여 Marshal 클래스의 ReadByte, ReadInt32 같은 메서드나 WriteByte, WriteInt32 같은 메서드를 통해 오프셋을 지정하여 주소 탐색을 간접 처리하는 것이 전부였습니다. 그렇지만 xPlatform에서는 +, -, ++, --, ==, != 등의 포인터에 대해서 사용할 수 있는 주요 연산자를 정의하는 커스텀 포인터 구조체들을 대거 추가하였습니다. 향후 이 부분을 템플릿화하여 직접 만든 구조체나 나열 상수에 대한 포인터도 사용자 정의할 수 있게 만들 생각입니다.
size_t 등의 Native C 형식 지원
닷넷의 Enum 형식은 생각보다 씀씀이가 많습니다. 특히 Primitive Type 중 정수 계열 (int, uint, short, ushort, long, ulong 등)을 enum으로 재정의하여 C/C++이 원래 사용하던 size_t 같은 형식을 그대로 재현할 수 있었습니다. 문법적으로도 size_t와 uint 사이는 관련은 있지만 명시적 변환이 이루어져야만 하는 원래의 코드에서처럼 C#에서도 동일하게 동작합니다.
ptr++, (ptr + i) 등의 표현식 지원
주소 탐색을 위하여 더 이상 어렵고 복잡한 간접 우회 코드를 사용하지 마시고, 그냥 C/C++에서 하던 것처럼 원소 수를 더하거나 빼서 주소 탐색을 하시면 됩니다. :-)
향후 계획
코어 파트는 좀 더 개선할 부분이 많고 테스트가 많이 필요합니다. 많은 분들의 참여와 관심을 통하여 개선을 시켜 나가야 할 것으로 생각합니다. 그리고 더 나아가서는 C++ Name Mangling 등의 복잡한 이슈를 직접 풀고 C#에서 바로 C++ 코드를 액세스할 수 있게 만드는 작업도 욕심을 내보고 싶습니다.
프로젝트 홈페이지는 http://blendxplatform.codeplex.com 이며 누구나 체크아웃해가실 수 있습니다. 서브 버전, TFS 등을 이용하여 쉽게 받아가실 수 있습니다.
Subversion 주소: https://blendxplatform.svn.codeplex.com/svn
TFS 주소: https://tfs05.codeplex.com
'Project Blend: > Cross Platform' 카테고리의 다른 글
| Project Blend: xPlatform 2009년 11월판 런칭 (0) | 2009/11/01 |
|---|---|
| Project Blend: xPlatform 작업 기록 (2009년 6월 29일) (0) | 2009/06/29 |
| Project Blend: xPlatform 작업 기록 (2009년 4월 2일) (0) | 2009/04/02 |
| CLIFX xPlatform Repository Open (0) | 2008/01/27 |
| xPlatform works in Linux! (0) | 2007/12/08 |
| Project Blend: xPlatform NEWS (0) | 2007/12/02 |