본문 바로가기
[ Program ]/C#

C#과 API

by 관이119 2012. 9. 18.
출처 sadmong님의 블로그 | 바람처럼
원문 http://blog.naver.com/sadmong/70001809582

C# and API

by Ajit Mungale

1. 소개

 

API(Application Programming Interface)는 프로세서와 더불어 프로그램 인터페이스를 구성하는 명령들의 집합이다.

외부 프로시져의 세트들은 보통 Microsoft 의 Windows 그 자체를 만든다.

Windows API 는 선언할 수 있고, 다시 그것을 사용할 수 있는 수천개의 함수와 구조체 그리고, 상수들로 이루어져 있다.

그러나, 이러한 함수들은 C언어로 작성되어져 있고, 그래서 사용되어지기 전에 반드시 선언되어져야 한다.

 

DLL 프로시져들의 선언은 더욱 복잡해질 수 있다.

특히 C# 에서는 비주얼베이직 보다 더욱 복잡하다.

당신은 API 함수 선언을 얻기 위해 API 뷰어 툴을 사용할 수 있다.

하지만, C#에서는 파라메터의 형이 기존과는 다르다는 것을 명심해야 한다.

 

수 많은 진보된 언어들이 API 프로그래밍을 지원한다.

MFC(Microsoft Foundation Class Library) 프레임웍은 Win32(API)의 큰 부분을 캡슐화 하고 있다.

ODBC API 함수들은 데이터베이스의 빠른 수행을 위해 유용하게 사용된다.

 

당신의 애플리케이션은 API의 도움으로 운영체제상에서 로우레벨 서비스들을 요청할 수 있다.

API 가 단순한 메시지 박스에서 암호화, 원격 컴퓨팅까지 수천가지의 기능들을 제공하므로,

개발자는 그들의 프로그램에서 API를 어떻게 구현할지를 알아야 한다.

 

API 는 OS, 프로세서 그리고 함수 의존적인 수많은 형들을 가지고 있다

 

2. 운영체제에 관한 API

 

각각의 운영체제는 몇몇 특이사항을 제외하고 공통된 API 세트를 가지고 있다.

WIndows NT 는 MS-DOS, Win16, Win32, POSIX(Potable Operating System Interface), OS/2 console API 그리고 MS-DOS를 지원하는 Windows 95, Win16, Win32 API 들을 지원한다.

 

3. Win16 & Win32 API

 

Win16 은 16비트 프로세서를 위해 만들어졌고 16비트 값들을 사용한다.

그리고 플랫폼 독립적인 특성을 가졌다.

Win32 는 32비트 프로세서를 위해 만들어졌고, 32비트 값들을 사용한다.

어떠한 운영체제와도 이동하기 편하며, 광범위한 프로세서와 플랫폼 독립적인 특징을 가지고 있다.

 

Win32 API 는 라이브러리 이름뒤에 '32'라는 접미사가 붙어있다. 예를 들면 KERNEL32, USER32 등이다.

 

모든 API 들은 3 개의 라이브러리를 사용해 구현되어져 있다.

● KERNEL

● USER

● GDI

 

4. KERNEL

 

이것은 아래와 같은 OS와 관련된 기능들을 지원하기 위해 "KERNEL32.DLL" 라는 라이브러리 파일명을 가지고 있다.

프로세스 로딩

● 컨텍스트 스위칭

● 파일 입출력

● 메모리 관리

예를 들면 GlobalMemoryStatus 함수는 시스템의 현재 물리, 가상 메모리의 상태에 관한 정보를 얻고 싶을때 사용한다.

 

5. USER

 

Win32 에서 이것은 "USER32.DLL" 이라는 라이브러리 파일명을 가지고 있다.

이것은 아래와 같이 모든 유저 인터페이스(UI)를 지원한다.

● 윈도우즈

● 메뉴

● 대화 상자

● 아이콘 등...

예를 들면, DrawIcon 함수처럼 특정 DC(Device Context)에 아이콘이나 커서를 그리는 것이다.

 

6. GDI (Graphical Device Interface)

 

그래픽 출력 라이브러리이며, Win32 에서 "GDI32.DLL" 이라는 라이브러리 파일명을 가지고 있다. 윈도우즈는 GDI를 이용해 윈도우, 메뉴, 그리고 대화상자등을 그린다.

● 이것은 그래픽 출력을 할 수 있다.

● 그래픽 이미지를 저장하기 위해서도 사용된다.

예를 들면, CreateBitmap 함수처럼 특정 폭과 높이, 색상을 가지는 비트맵을 생성하는 것이다.

 

7. C# 과 API

 

C# 에서 API를 구현하는 것은 초보자에게 어려운 일이다.

API를 구현하기 전에 반드시 C#에서 구조체를 어떻게 구현하는 지를 알아야 하며, 형변환, safe/unsafe 코드, managed/unmanaged code 등 많은 것을 알아야 한다.

 

복잡한 API 를 구현하기 전에 일단 단순한 MessageBox API 부터 구현해 보기로 하자.

새로운 C# 프로젝트를 생성하고, 버튼 하나를 추가하자. 버튼이 클릭되면, 코드는 MessageBox 를 출력하게 할 것이다.

외부 라이브러리(external library)를 사용하기 위해, 일단 다음과 같은 네임스페이스를 추가한다.

 

using System.Runtime.InteropServices;

 

API 를 선언하기 위해 아래 라인을 추가한다.

[DllImport("User32.dll")]

public static extern int MessageBox(int h, string m, string c, int type);

DllImport 속성(attribute)는 unmanaged code 에서 메소드를 호출하기 위해 사용되었다.

"user32.dll" 은 라이브러리 이름을 나타낸다.

 

DllImport 속성은 외부 메소드의 구현이 포함되어 있는 특정 dll 파일의 위치를 명시한다.

static 변경자는 특정 객체보다 선언된 형 그 자체를 의미하는 정적멤버를 선언하기 위해 사용되었고,

extern 은 외부에 메소드가 구현되어 있음을 나타내기 위해 사용된다.

DllImport 속성으로 꾸며진, 메소드는 반드시 extern 변경자를 가져야 한다.

 

MessageBox 는 함수 이름이며, 선언에서 보이는 것처럼 int 를 리턴하며, 4개의 파라메터를 가진다.

많은 API 들은 효율성을 위해 값들을 주고 받기 위해 구조체를 사용한다.

또한 이전의 MessageBox 함수의 선언에서 본것처럼 기본자료형들을 전달하기 위해 단순자료형을 사용하고,

상수형의 데이터를 전달하기 위해 상수형을 사용한다.

 

버튼 클릭 이벤트에 아래의 코드를 덧붙인다.

 

protected void button1_Click (object sender, System.EventArgs e)

{

MessageBox (0,"API Message Box","API Demo",0);

}

컴파일 후 프로젝트를 실행시키고, 버튼을 클릭해보면 당신이 API 함수를 사용해 호출한 MessageBox 를 볼 수 있을것이다.

 

8. 구조체 사용하기

 

API 를 사용하면서 복잡한 구조체나 구조체속의 구조체등은 단순한 API 의 사용보다 다소 어렵다.

다음의 예제에서 우리는 현재 시스템의 정보를 리턴하는 GetSystemInfo() 함수를 사용할 것이다.

일단 새로운 C# 폼을 열고, 버튼을 하나 추가해 보자. 코드윈도우로 전환한 후 네임스페이스를 추가하자.

 

usingSystem.Runtime.InteropServices;

 

그리고 GetSystemInfo 의 파라메터로 사용할 구조체를 선언하자.

[StructLayout(LayoutKind.Sequential)]

public struct SYSTEM_INFO {

public uint dwOemId;

public uint dwPageSize;

public uint lpMinimumApplicationAddress;

public uint lpMaximumApplicationAddress;

public uint dwActiveProcessorMask;

public uint dwNumberOfProcessors;

public uint dwProcessorType;

public uint dwAllocationGranularity;

public uint dwProcessorLevel;

public uint dwProcessorRevision;

}

그리고 API 함수를 선언한다.

[DllImport("kernel32")]

static extern void GetSystemInfo(ref SYSTEM_INFO pSI);

ref 는 메소드에 전달된 변수가 원래의 변수를 참조할수 있게 하는 메소드 파라메터 키워드이다.

버튼이 클릭되었을때 구조체를 생성하고 함수의 파라메터로 전달할수 있게 하기 위해서 아래의 코드를 추가하자.

protected void button1_Click (object sender, System.EventArgs e)

{

try

{

SYSTEM_INFO pSI = new SYSTEM_INFO();

GetSystemInfo(ref pSI);

//

//

//

        //

//

//

}

        catch(Exception er)

{

MessageBox.Show (er.Message);

}

}

덧붙여진 코드에서 난 다양한 시스템의 정보를 얻어내기 위해 2개의 API 를 사용하였다.

주의사항 :

심플한 애플리케이션을 생성하기 위해 난 beta 버전 1.0 을 사용하였다. 베타 2.0 에서는 API 의 선언이 아마도 1.0에 비해 약간 다를 것이다.

댓글