[Console] DllImport

2011. 9. 14. 20:52C#/Console

DllImport 특성을 이용하면 C# 에서 WinAPI 를 다룰수가 있다. 
역시나 예제가 있어야 겠다.

// Dll_import.cs
using System;
using System.Runtime.InteropServices;

class MainApp
{
    [ DllImport("user32.dll") ]
    public static extern int SendMessage(int hWnd, uint Msg, long wParam, long lParam); 

    public const int WM_CLOSE = 0x0010; //닫기

    public static void Main()
    {
        Console.WriteLine("user32.dll 의 SendMessage 함수를 쓰겠다.");
        SendMessage(0x000103AC, WM_CLOSE, 0, 0);
    }
}


위의 코드를 실행하면, Window handle(hWnd) 이 0x000103AC 인 윈도우를 닫는다.
위의 예제에서는 SendMessage() 함수가 인자 중에 특정한 구조체를 받는 행위가 없다.
만일 인자 중에, 어떤 구조체가 들어가는 경우는 어떤가 ?

이번엔 WinAPI 의 GetSystemTime() 를 사용해보자. kernel32.dll 의 GetSystemTime() 함수의 원형은 다음과 같다.

void GetSystemTime( LPSYSTEMTIME lpSystemTime );


내가 작성하는 C# 소스코드에서 읽어들이는 kernel32.dll 파일 안에 SYSTEMTIME 이란 구조체가 정의되어 있을리 없다.
그러므로, 저 GetSystemTime() 함수를 사용하기 위해서는 SYSTEMTIME 구조체를 정의해 줘야 한다.
(msdn 을 찾거나. 헤더파일에서 찾아야 한다고 하네..  와! 이건 참 짜증나는 일이구나!)

아무튼... SYSTEMTIME 구조체의 원형을 찾아서 확인해보면 다음과 같다.

typedef struct _SYSTEMTIME
{
    WORD wYear;
    WORD wMonth;
    WORD wDayOfWeek;
    WORD wDay;
    WORD wHour;
    WORD wMinute;
    WORD wSecond;
    WORD mMilliseconds;
} SYSTEMTIME;



C#에서는 WORD 라는 표현을 쓰지 않는다. WORD 는 16비트 부호없는 정수 이므로. 
가져가 쓰는 입장(C#)에서는 ushort 를 사용하면 되겠다.


// Dll_import2.cs
using System;
using System.Runtime.InteropServices;

class MainApp
{
    [ DllImport("kernel32.dll") ]
    private static extern void GetSystemTime( ref SYSTEMTIME systemtime );

     struct SYSTEMTIME
     {
         ushort wYear;
         ushort wMonth;
         ushort wDayOfWeek;
         ushort wDay;
         ushort wHour;
         ushort wMinute;
         ushort wSecond;
         ushort mMilliseconds;
     } 
  
    public static void Main()
    {
        Console.WriteLine("kernel32.dll 의 GetSystemTime 함수를 쓰겠다.");
        
        SYSTEMTIME systemtime = new SYSTEMTIME();
        GetSystemTime(ref systemtime);
    }
}


자!!  조심해야 할 사항이 있다. 
[ DllImport("kernel32.dll") ] 를 정의해 놓은곳은, 메쏘드 안에서 하지 않는다.  
만일 Main() 메쏘드 아래에서 정의하게 되면, 400번하면 400번 에러난다.  400원건다.
  

아래 링크에서 본 내용을 옮겨적는 내용이다.  그러므로 아래 링크만 봐도 된다. 
난 무식해서 이렇게 정리 안해놓으면 금방 까먹는다.

'C# > Console' 카테고리의 다른 글

[C#] 이동평균  (0) 2011.11.22
[Console] 숫자만 입력받기  (0) 2011.09.21
[Console 08.23] 완벽한 코드  (0) 2011.08.23
[Console] C# 문자 변환  (0) 2011.08.04
[Console]using 사용법  (0) 2011.06.10