MIGRATION

 

사전적인 의미의 MIGRATION 이란??

MIGRATION의 사전적인 의미는 위와 같이 정의되어있다. (네이버 사전 참조)

위의 내용에서도 나타나 있듯이 (컴퓨터 시스템 * 프로그램의) 이송[이행]을 나타내는 것을 사전적 의미의 마이그레이션이라 한다. 그렇다면, 전산적인 의미의 마이그레이션에 대해서 자세히 알아보도록 하자.

 

 

 

전산적인 의미의 MIGRATION 이란?

전산적인 마이그레이션은 하나의 운영환경에서 다른 운영환경으로 옮긴다는 의미이다. 실제로 마이그레이션을 사용하는 예로써, 큰 의미에서는 WINDOWSNT 환경에서 UNIX 환경으로 OS 의 이동부터, 작은 의미에서는 WIN32API(NATIVE CODE)를 다른 언어에서 사용하는 것 까지 종류가 다양하다. 또 데이터베이스 끼리의 환경이동이나, 하드웨어, 소프트웨어 끼리의 환경을 옮겨 가는 것 또한 MIGRATION 이라 한다.

 

 

 

마이그레이션의 이점

앞서 말한것과 같이, 마이그레이션은 하나의 운영환경에서 다른 운영환경으로 환경을 옮겨가는 것을 말한다. 이로써 얻을 수 있는 장점으로서는, 우선 기존의 환경에 있던 설정이나, 프로그램 등을 다른환경에서 사용할 수 있다는 큰 장점이 있고, 이로 인해 재사용성이 용이하며, 개발비용 절감 효과를 얻을 수 있다.

  또 다른 이점으로는, 기존의 환경과, 옮기려는 환경의 특징을 모두 사용 할 수 있다는 큰 장점이 있다. 이를 통하여 보다 더 나은 프로그래밍 환경을 보장 받기 때문에, 마이그레이션은 개발자들에겐 이점이 되는 기술이다.

 

 

WRAPPING CLASS

 

 

래핑 클래스란??

래핑클래스란, 사용자의 편의를 위해 만들어진 클래스로서, 사용법을 숙지하지 못한 사용자나, 함수를 능숙하게 사용하지 못하는 사용자를 위해 만들어 놓는 클래스이다. 래핑클래스를 통해서 사용자는 간단한 함수호출로써 함수들을 사용 할 수 있다. 이로 인해서 함수 사용의 문제를 해결 할 수 있다.

하지만 주의할 점으로는, 래핑클래스를 제대로 구현을 하지 않았을 경우, 사용자는 에러를 잡아내기 힘들며, 구현에 혼란이 올 수도 있다.

 C#에서 래핑클래스를 작성할 경우, 포인터나 가비지 컬렉터, 소멸자에 대한 지식이 필요하며, 주의하여 래핑클래스를 작성해야한다.

 

C#에서 MIGRATION 을 하기위한 키워드들

 

DllImport

       외부 DLL을 호출하기 위한 어트리뷰트

       사용하고자 하는 메소드 형식을 이미 알고있어야 함.

       Using System.Runtime.InteropServices

 

 

Unsafe

       안전하지 않은 컨텍스트를 나타냄

       포인터에 관련된 모든 작업에 필요

       형식이나 멤버의 전체 텍스트 범위가 안전하지 않은 것으로 처리

 

 

fixed

       GC가 변수를 재배치할 수 없도록 함

       unsafe 컨텍스트에서만 사용가능

       고정크기버퍼를 만들 때 Fixed 문을 사용할 수도 있음.

 

 

C# 에서 래핑클래스를 작성하기 위한 키워드

 

assembly : System.CLSCompliant(true)

       C# 컴파일러가 코드의 CLS준수 여부를 검사

 

마이그레이션 & 래핑클래스 실습

 

실습내용

      Data.txt 파일의 내용을 10칸의 내용만 콘솔창에 출력

      Messagebox함수를 사용하여 출력.

 

작성순서

      클래스를 하나 만들어 Win32API에 있는 함수를 DllImport 한다

      kernel32.dll ( CreateFile , ReadFile , CloseHandle )

      User32.dll ( MessageBox )

      Import 한 함수에 대한 래핑클래스를 작성한다

 

 

함수를 Import 하는 클래스

class NativeMethod

    {

        //네이티브메소드

        [DllImport("Kernel32")]

        public extern static IntPtr CreateFile(string fname, uint DesiredAcess,

uint ShareMode, uint se, uint Dispotion, uint flags, int hTem);       

        [DllImport("Kernel32")]                

        public extern static void CloseHandle(IntPtr hFile);

        [DllImport("Kernel32")]                         

unsafe public extern static int ReadFile(IntPtr hFile, byte *Buffer,

 int numRead, int * Readed, int overlapped);

        [DllImport("User32.dll")]

        public static extern int MessageBox(int i, string text, string title, int type);

        //사용할 상수 정의

        public const int INVALID_HANDLE_VALUE = -1;

        public const uint GENERIC_READ = 0x80000000;

        public const uint OPEN_EXISTING = 3;

    }

 

 

함수를 Import 하는 클래스 (설명)

함수를 Import 하는 클래스를 NativeMethod 로 지정하였다.

이 클래스에서는 CreateFile, CloseHandle, ReadFile, MessageBox 이렇게 4가지 WIN32API 함수들을 Import 하고 있다.

 또 필요한 상수인 INVALID_HANDLE_VALUE, GENERIC_READ, OPEN_EXISTING 을 정의해주었다. 이 상수들은 헤더에 정의되어 있으므로, 직접 정의해야한다.

  함수를 Import 할때는 [DllImport(“DLL”)] 이런식으로 어트리뷰트를 사용해야한다.

 

 

Main 함수 부분

class Program

    {

        static void Main(string[] args)

        {  

            //NativeMethod 이용 예

            IntPtr hFile = NativeMethod.CreateFile("ad.txt",

           NativeMethod.GENERIC_READ, 0, 0, NativeMethod.OPEN_EXISTING, 0, 0);

            Console.WriteLine("{0}", hFile.ToString());

            byte[] arr = new byte[100]; // 바이트배열선언

            unsafe //안전하지않은 형식

            {

                fixed (byte* p = arr) // 포인터 p arr을 가리킴

                {

                    int h;

                    NativeMethod.ReadFile(hFile, p, 10, &h, 0); // ReadFile호출

                }

                char[] carr = new char[100]; // 캐릭터배열

                //byte -> char

                Decoder d = Encoding.ASCII.GetDecoder();

                d.GetChars(arr, 0, 10, carr, 0);

                String s = new string(carr);//char -> string

 

                NativeMethod.MessageBox(0, s, "결과", 0);

                Console.WriteLine(s);

            }

            NativeMethod.CloseHandle(hFile); // 핸들닫기

        }

    }

 

 

Main 함수 부분(설명)

 Main 함수 내부는 좀 전에 생성한 NativeMethod 에 있는 함수를 호출하는 부분이다. 사용할때 unsafe, fixed 키워드를 사용하였는데, 이는 포인터를 사용하기 위하여 사용되었다. 이 예제는 ad.txt 에 있는 파일의 내용을 10칸만 가지고와서 화면에 출력하는 예이다.

 래핑클래스를 사용하지 않을경우, 이렇게 사용하기 복잡하고 어렵게 된다. 래핑클래스의 정의 부분을 살펴보자.

 

 

래핑클래스 사용

[CLSCompliant(true)]//다른언어에서도 사용가능한 안전함. native직접 or 래퍼.

    public class FileWrap

    {

        // 파일 변수

        IntPtr hFile;

       

        //파일생성

        public FileWrap(string fname)

        {

            // NativeMethod 에 있는 CreateFile 을 호출한다.

            hFile = NativeMethod.CreateFile(fname, NativeMethod.GENERIC_READ, 0, 0, NativeMethod.OPEN_EXISTING, 0, 0);

        }

        //파일읽기

        public string Read(ref int nbyte) // 매개변수로는 읽어올 양을 결정

        {// 파일 변수가 잘못된 핸들인지 검사           

            if (hFile ==(IntPtr) NativeMethod.INVALID_HANDLE_VALUE) {

                throw new ApplicationException("잘못된 파일 핸들"); // 예외발생

            }

            byte[] arr = new byte[nbyte]; // 바이트 배열 생성.

            String s= string.Empty; // 스트링 변수를 하나 생성.

           

            unsafe // 포인터를 사용하기때문에 unsafe 키워드 사용

            {

                int h;

                fixed (byte* p = arr) // 가비지컬렉터의 관리영역제외

                {                   

                    NativeMethod.ReadFile(hFile, p, nbyte,&h, 0);

                } // Byte -> Char 을 위해서 캐릭터배열을 생성

                char[] carr = new char[h];

                Decoder d = Encoding.ASCII.GetDecoder(); //디코더를 생성 후          

                d.GetChars(arr, 0, h, carr, 0); // h만큼의 문자열을 carr 에 채운다               

                s = new string(carr); // carr 를 스트링 형으로 생성

            }                       

            return s;

        }

        //파일닫기

        public void Close()

        {// 파일변수에 이상이 없을때

            if (hFile != (IntPtr)NativeMethod.INVALID_HANDLE_VALUE)

            {

                NativeMethod.CloseHandle(hFile); // 종료

            }

            hFile = (IntPtr)NativeMethod.INVALID_HANDLE_VALUE;

        }

        //메시지박스

        public void MessageBox(string text)

        {

            NativeMethod.MessageBox(0, text, "결과", 0);

        }

        //소멸자

        ~FileWrap()

        {

            Close();           

        }

 

래핑클래스 사용 (설명)

 다음은 래핑클래스를 정의한 부분이다. 사용자는 이 클래스에서 공개해둔 함수들을 통해 복잡한 작업을 하지않고 일을 처리 할 수 있다.

 여기서 중요한 부분이 있는데 바로 소멸자 부분이다. 흔히 소멸자를 신경쓰지않고 코딩할 경우가 많이있다. 소멸자는 가비지컬렉터가 호출하게 되는데, 소멸자에서 Close(); 함수 호출을 통해 CloseHandle 작업을 해주는 것을 볼 수 있다.

 

 

정리

 마이그레이션을 통해 WIN32API NATIVECODE C#에서 사용하는 것에 대해서 알아보았다. 마이그레이션을 통해 코드의 질을 높힐 수 있고, 재사용성을 통해서 얻을 수 있는 장점이 매우 큰 것 같다.

 마이그레이션 학습을 통해 코딩스킬을 다양하게 익힐 수 있기 때문에 마이그레이션에 대한 학습을 더 많이 해야겠다고 생각한다.

 


'COMPUTER TECH > C# 실전자료' 카테고리의 다른 글

WPF 사용자정의 컨트롤을 WinForm 에서 사용하는 법  (0) 2010.08.13
RCW  (0) 2010.08.13
Migration (API -> C#)  (0) 2010.08.13
Migration (COM -> C#)  (0) 2010.08.13
사용자 정의 컨트롤  (0) 2010.08.13
ListBox Animation  (0) 2010.08.13
Posted by ... XJAPAN