|
| Posted by 지상현 | 2005-09-04 21:48:00, Hit : 7276 | |
|
|
|
--------------------------------------------------------------------------------- 이번에는 진짜로 다른 언어로 된 선언문을 창조식으로 바꾸는 방법에 대해 알아봅니다. 계속 존칭 생략하죠 -_-; ---------------------------------------------------------------------------------
6. 윈도를 만든 C, 너부터 까발린다! C로 되어 있는 선언문을 살펴본다
지금까지 이론적으로(?) 뭐가 어떻게 되어있는지 재미 없게 떠들었지만, 드디어 실전(?)이다. 먼저 가장 많이 있는 C로 된 선언문을 옮겨보자.
먼저 간단한 예를 분석해보며 해보자.
BOOL MessageBeep( UINT uType // sound type );
일단 대충 봐도 감이 올 것이다. 여러 줄로 되어 있는데, C에서는 줄바꿈이 의미가 없다. 한줄로 만들어서 보면 그만이다.
*1) C에서는 줄바꿈이 의미가 없으니 무시한다.
먼저, 가장 앞에 BOOL이 보이는가? 이 것은 바로 함수의 반환 형식이다. BOOL이 뭔지는 모르지만, 창조와 비슷하므로 반환값이라는 느낌이 딱 올 것이다.
*2) 가장 처음에 나오는 것이 바로 반환 형식이다.
그 다음에 나오는 것은 설명할 필요가 없다. 바로 함수 이름이다. 여기서 주의할 점이 있는데, C 에서는 반드시 저 함수 이름이 아닐수도 있다. 이 C~ 이게 대체 뭐야! 하겠지만... 어려운건 아니다. 그 것은 밑에서 설명하기로 하고 일단은 넘어가자~
그 다음에 소괄호로 둘러싸인 부분이 있다. 소괄호 부분이 바로 인자 목록이다. 이 역시 창조와 비슷하게 “인자형식 인자이름” 으로 되어 있다. 띄어쓰기가 구분자이다. 또 각각의 인자들은 쉼표로 구분되어 있다. 전혀 어렵지 않은 구조이다.
*3) 인자는 다음과 같이 나열되어 있다. 인자형식 인자1, 인자형식 인자2, ...
인자 이름은 자기 멋대로 지정해줄 수 있다. 그리고 괄호 바깥을 나가서 문장의 끝이라는 것을 알려주는 ; 로 끝이 난다. 주의 할 점이 있는데, * 기호가 붙어 있다면 그 것이 인자 이름에 붙어 있더라도 실은 인자형식에 붙는 것이다.
아주 쉽다. 문제는 C의 형식이 창조의 어떤 형식과 대응하는지일 것이다.
창조에서 실수에 해당하는 형식 * 가 붙은 모든 형식(* 는 여러개 붙을 수도 있다, 예: void*, int*, DWORD*...) ※char* 는 제외! char, short, long, int float, double UINT, ULONG, USHORT BYTE, WORD, DWORD BOOL, bool FLOAT, DOUBLE 'H' 로 시작하는 형식들(예: HWND, HANDLE, HMENU, HDC...)
창조에서 반환값이 그냥 '함수'가 되는 형식 void, VOID
간혹 가다가 앞에 signed, unsigned 가 붙은 경우가 있는데 상관 없이 무시해도 좋다(참고적으로 창조는 무조건 signed, 붙어있지 않은 형들은 모두 signed). C에 형식이 무지 많은데, 사실 모두 매크로라는 것으로, 소문자로 된 기본형으로 바뀌어서 컴파일 된다.
창조에서 문자에 해당하는 형식 char* PSTR, LPSTR, LPTSTR, LPCTSTR
일단 저 정도가 된다. 뭐가 이래! 라고 외칠 수 밖에 없다. 하지만 따지고 보면 저 것들은 모두 같다(!).
먼저 L 이 붙은 형식에 대해 생각해보자. L은 Long의 약자로, 옛 16비트 시대의 산물이니 완전히 무시할 수 있다. 그 다음에 붙은 P는, 포인터Pointer란 뜻이다. 문자형은 모두 포인터이므로, 그냥 그렇다는 것을 알고 무시해도 된다. 뒤에 있는 STR은 문자열String의 약자라고 추측할 수 있다.
문제는 더러 붙어있는 T와 C 인데, 그 것도 간단하다.
먼저 T가 붙어있는 경우는, 이 문자열은 NULL(간단히 0이라고 생각하면 된다. 다만 값이 0인 포인터이다)로 끝나는Terminate 되는 거다~ 라는 뜻이다. 붙어 있고 안붙어있고는 중요하지 않다. 어차피 모든 API에서 쓰는 문자열은 NULL로 끝나는 문자열이다 -_- (↑ 이것은 아래 댓글을 참고한다)
C가 붙어있으면, 이 문자열은 상수Constant 라는 뜻이다. 상수란, 값이 변하지 않는 일종의 변수이다. 말이 이상하다 -_- 여하튼 C가 붙어있으면 이 문자열은 변하지 않는다 라는 보증이 된다. 이상하게 들릴지도 모르겠지만... 붙어있지 않은 경우도 있는데, 이 경우는 문자열의 내용이 함수를 다녀온 다음에 어떻게 변할지 나도 몰라요 란 뜻이다. API에서 문자열은 거의 반환값으로 전달되지 않고, 인자로 넘겨졌다가 함수가 끝나면 그 문자열에 결과값이 몰래 들어가있는 형태로 반환된다. 이 점을 기억해야 한다.
나머지 형식들, 그러니까 LP 로 시작하는 형식들... 예를 들어 LPPOINT, LPRECT 는 모두 구조체 형식이다. 그러니까 어쩔 수 없이 포기해야 한다. 몇 가지는 쓸 수 있는 경우도 있다. 구조체도 P가 붙어있듯이, 그저 포인터이기 때문이다. 포인터 형식은 필요에 따라 실수로도, 문자로도 임의로 고쳐 쓸 수 있다는 점만 명심하고 이만 접도록 하자.
아, 여기에는 DLL 파일 이름이 적혀있지 않다. 이 것은 전적으로 동봉된 문서나 MSDN에서 찾아봐야 한다 -_- 위 예에서 든 함수는 kernel32.dll 안에 있다.
7. 이번엔 델파이다! 델파이는 거의 일대일로 번역하면 된다
이번에는 델파이다. 델파이는 무지 쉽다. 창조와 거의 똑같은 형식이기 때문에 그냥 글자만 몇 가지 바꿔주면 된다.
function MessageBeep(uType: Cardinal): LongBool; stdcall; external 'kernel32.dll'; name 'MessageBeep';
별 거 아닌데 어려워 보인다. 가장 앞에 function 은 반환값이 (뭐가 됐던) 일단 있다는 뜻이고, 만약 procedure 라고 적혀 있다면 반환값이 없다는 뜻이다.
이 사실을 간단하게 요약해보자. function 함수이름(인자): 반환형식; 기타 잡다한 것들... procedure 함수이름(인자); 기타 잡다한 것들...
차이점을 잘 보자. function 이면 괄호가 끝난 다음 뭔가 더 붙어 있다. 이게 바로 반환 형식이다.
*1) 일단 델파이도 줄바꿈은 의미가 없다. 무시한다.
*2) 가장 처음에 procedure가 나오면 반환 형식이 없는 것이고, function 이라면 반환 형식이 있되, 괄호 다음에 : 과 함께 나온다.
그 다음에 나오는 것이 함수 이름인데... 일단 제껴두고 뒷부분을 잘 보자. name 다음에 있는 ' 으로 둘러싸인 문자열... 이 것이 실제로 사용되는 함수의 이름인 것이다. 속으면 안된다! 다만 name 이 없을 때는 그냥 함수 이름을 써야 한다. (※델파이는 일반적으로 저렇게 몽땅 붙여쓰지 않는다. 먼저 함수의 인자와 이름, 반환 형식, 호츨 방법등을 정의하고, 또 다른 곳에 DLL 과의 연결 정보를 적는다)
이제 괄호 안이다. 인자 목록이 있는데, 창조와 같기 때문에 이해가 매우 쉬울 것이다. 주의할 점은, 인자 이름과 형식이 거꾸로 있다는 것이다. 예를 들어 창조로 문자:문 이라면 델파이로는 문:문자 같은 식이다.
*3) 인자들은 창조와 같은 방법으로 나열되어 있되, 인자 이름과 형식이 반대다.
여기까지 별어려움 없이 이해했을 것이다. 이제 뒷부분을 살펴보도록 하자.
stdcall - 이 함수가 stdcall 을 따르고 있다는 것을 알려준다. 창조에선 stdcall 만 쓸 수 있다. external '문자열' - 이 함수가 '문자열'에 있는 DLL과 연결되어 있다는 뜻이다. 친절하게도... name '문자열' - 위에서 언급했듯이, 실제로 DLL과 연결되는 함수의 이름이다. 없을 수도 있다.
*4) 괄호 밖 꽁무니에 DLL 파일 이름과 실제 사용되는 함수 이름이 들어있다.
어떤가? 어렵지 않다. 역시 문제되는 것은, 변수의 형식인데... 또 대조해보자.
창조에서 실수에 해당하는 형식 Boolean Char, ShortInt, SmallInt, LongInt, Integer Byte, Cardinal, Word, LongWord Single, Double
API는 델파이라도 C 처럼 해놓은 경우도 있으니 그 것은 C 형식을 참고하면 된다.
창조에서 문자에 해당하는 형식 String, PChar, AnsiString, ShortString
갈수록 설명이 허접해지고 지루해지는 면이 없지않아 있지만...-_- 변수 형식에 T 가 붙어있으면 십중팔구 구조체이므로 포기하면 된다 -_-
아.... 인자가 나열되어 있을 때 var a: Integer 처럼 앞에 var가 붙어있을 수도 있고, 또는 const가 붙어있을 수도 있다.
var - C랑 비교하면 * 이다. 즉, 포인터로 이해하면 된다. const - 역시 C의 설명에서처럼 -_- 값이 변하지 않는다는 뜻이다.
자세한 것은 C의 설명을 참조하면 된다 -_-
8. VB도 정복해보자! VB는 C와 델파이와 같이 이해하면 쉽다
VB는 훨씬 쉽다. 왜냐하면, C나 델파이는 형식의 이름을 새롭게 정의할 수 있는데다, 같은 크기라도 부호가 있는 형과 없는 형들이 있어서 무지하게 많아보이기 때문이다 -_-; 하지만 VB는 그런게 없어서 쉬울 것이다.
Public Declare Function MessageBeep Lib "kernel32.dll" Alias "MessageBeep" (ByVal uType As Long) As Long
또 하나하나 분석해보자... 델파이를 생각하면서 읽으면 매우 쉽다.
가장 먼저 나오는 Public...무슨 뜻일까? 그저 무시하면 된다. 이 것은 이 함수를 사용할 수 있는 범위에 대한, 상관 없는 것이다.
그 다음에 나오는 Declare. 이 것은 이 함수가 DLL 에 있는 함수라는 뜻으로, 친절하게도 별 걸 다 알려준다.
*1) 앞부분에 잔뜩 나온 Public, Declare 는 의미가 없다.
그 다음에 나온 Function... 어디서 많이 본 것 같다? 그렇다. 델파이에서처럼 Function은, 반환값이 있다는 뜻이다. 그럼 반환값이 없는것도 있을 텐데? 있다. 그렇지만 VB에선 Sub 라고 쓰니 참고하자. Function이 아니고 Sub 라면, 괄호 다음에 아무 것도 없을 것이다.
*2) Function이 있으면 반환값이 있는 것이고, Sub가 있으면 없다. 반환 형식은 괄호 다음에 붙는다.
그 다음에 나온 것, Lib "kernel32.dll" 딱히 설명할 필요는 없을 것 같다. kernel32.dll 이란 라이브러리Library 를 참조한다는 뜻이다. VB도 친절하게 DLL 파일 이름을 알려준다.
*3) Lib 다음에 친절하게도 사용하는 DLL 파일 이름이 적혀있다.
그 다음에 나오는 Alias "MessageBeep" 델파이를 떠올렸다면 정확하다. 델파이의 name 과 같은 역할이다. 진짜 함수 이름을 적어준다. 물론 없을 수도 있는데, 이 것이 있다면 이 것을 적어주는 것이 바람직 할 것이다.
*4) Alias 라는 게 있다면, 그 다음에 진짜 함수의 이름이 적혀있다.
드디어 괄호가 나왔다... 역시 간단하다.
ByVal uType As Long
자자. 잘 보자. ByVal 이란 무엇인가? 이것은 무시해도 좋은 것이다. 굳이 설명하자면, 인자를 넘길 때 값을 보낸다는 뜻이다. 무슨 뜻이냐고? 흠... 변수의 값을 보낸다는 뜻이다. 어? 그냥 변수를 넣으면 변수의 값이 가지 뭐 다른게 가나? 그렇다. 그렇기에 의미가 없다 -_- VB식으로 표현하면, C나 델파이는 기본적으로 ByVal 인 게다. 그런데 ByRef 가 붙어있거나 아무것도 붙어있지 않은 경우가 있다. 아무것도 안붙어있으면 ByRef 이다. 그럼 ByRef 는 뭐지? 델파이의 var 를 떠올리면 된다. 그저 포인터인 것이다. 이렇게 간단하게 설명해 버릴 수 있다.
그 다음에 uType 은 인자의 이름이고, As 다음에 나오는게 바로 인자의 변수 형식이다.
*5) ByVal은 무시하고, ByRef 나 아무것도 없으면 포인터이며, As 다음에 나오는게 변수 형식이다.
이제 괄호를 벗어나면 또 As Long 이 있다. 이 것도 델파이처럼, 함수가 Function 인 경우 반환값을 지정해준다. Sub 이면 이 것이 없다.
*6) 괄호를 넘어서 붙은 As...는 함수의 반환 형식이다.
아으....힘들다 -_- VB는 변수 형식이 몇 없으니 간단하다. 공식적으로 포인터란 것도 없어서 더욱 좋다(흐흐)
창조에서 실수에 해당하는 형식 Byte, Integer, Long Single, Double
창조에서 문자에 해당하는 형식 String (주의! 이 형식은 무조건 ByVal 이 붙어있어야 한다)
이게 끝이다. 얼마나 간단한가? -_-; 참 허접하고 짜증나는 설명이겠지만 열심히 읽으면 스스로 잘 바꿀 수 있을것이다 -_-;
9. 함수의 진짜 이름에 대해서 문자 형식이 사용되는 함수는 진짜 이름이 아니다
자... 위에 읽어보면서 깨달은 것이 있을 것이다. 함수 이름이 있는데 “진짜 이름” 은 또 뭐지??
일반적으로, 인자에 “문자” 형식이 있는 함수만 해당되는 내용이다. 문자가 없으면, 함수 이름과 진짜 이름은 대부분 일치한다.
문자 형식이 있으면 어쩌라고? 그냥 함수 이름 끝에 A 를 붙여준다. 왜?
그 이유는, 윈도가 문자를 관리하는 체계가 두 가지이기 때문이다. 그래서 문자가 있는 함수는 두 가지 버전이 각각 따로 있고, A나 W를 붙여 구분한다.
A가 붙는 경우는 일반적인 문자 코드를 쓴다는 뜻이다. 한국어 윈도라면, 영어는 1바이트, 한글은 2바이트다. 다른 언어의 윈도도 대부분 영어는 1바이트고 그 언어는 2바이트다. 이렇듯 각각의 문자 코드(코드 페이지)를 사용하는 함수를 ANSI 군 함수라고 하고, 함수 이름 끝에 A를 붙인다. A는 ANSI의 첫 글자다.
W가 붙은 경우는 유니코드를 쓰겠다는 뜻이다. 어떤 언어 버전의 윈도에 상관 없이, 무조건 한 글자가 2바이트를 차지한다. 이런 유니코드를 사용하는 함수를 Unicode 군 함수라고 하고, 함수 이름 끝에 W를 붙인다. W는 Wide String의 첫 글자다.
그래도 무조건 A를 사용한다. 왜냐고? W 는 Windows 2000 이상부터나 지원하기 때문이다 -_-
유니코드를 쓰는 게 좋지만, 호환성을 위해서 A를 쓰는 수 밖에 없는 것이다 ㅠㅠ
3회 강좌 끝
아으...이거 진짜 힘들군요 -┏ 그래도 끝은 봐야죠 -.-
다음에는 아마도, 못다한 포인터에 대한 지겨운 설명과 -_-; 인자에 대한 비밀 몇 가지를 알려드릴 것 같네요.
설명이 참 뭐같으니 이해 안가는 부분을 질문해주세요... |
|
|
정성우 2005-09-05 PM 4:46:10 |
|
|
|
델파이로 DLL만드는 것도 다음에 좀.... ^^;; |
|
|
지상현 2005-09-05 PM 5:13:29 |
|
|
|
아하...그 부분은 이진백님이 전문인데... |
|
|
qkrwhdgns 2005-09-05 PM 5:20:06 |
|
|
|
지금.. 내일 시간표에 맞추어서.. 교과서 챙기고.. 있는 도중에..
보았는데;; 좋은 내용이네요^^ (지루하고.. 했지만;;)
한번.. 테스트로.. API하나.. 골라서.. 해봐야지;; |
|
|
qkrwhdgns 2005-09-05 PM 5:56:27 |
|
|
|
그냥.. 아무거나.. 해볼려고.. 했는데;; 그냥.. 가장 쉬운거.. 하나 골라 했습니다.;;
DLL : user32.dll
--------------
실수함수:SetWindowTextA(실수:hWnd;문자:lpString);
--------------이거.. 원래.. C입니다. ;;---------
--------------버튼0.클릭했을때---------------
사용자함수0.SetWindowTextA(창0.핸들,"테스트");
-------------
이러니까 창0 이라는.. 이름이.. 테스트로 바뀌는;; |
|
|
지상현 2005-09-05 PM 6:46:40 |
|
|
|
헤헤, 하나 해내셨군요.
창조용 API 뷰어나 하나 만들어야 하는데...끄윽 |
|
|
qkrwhdgns 2005-09-05 PM 7:28:33 |
|
|
|
창조용 API 뷰어라.. ^^
굉장한.. 노가다(?) -_-ㅋ |
|
|
qkrwhdgns 2005-09-25 PM 12:15:46 |
|
|
|
API로.. 메시지 박스로 띄어봤습니다. ^^
MessageBoxA 인가.. 하는.. 함수로요.. |
|
|
이진백 2005-10-09 AM 10:35:18 |
|
|
|
아주 이해하기 쉽고 간편한 강좌로군요!
저도 몰랐던 몇가지를 배워하겠습니다.
정성우//강좌 진행하겠습니다. 고맙습니다! |
|
|
지상현 2005-10-09 PM 1:55:45 |
|
|
|
으어~ 고마워요~ -_-; |
|
|
박종훈 2006-02-10 PM 3:55:51 |
|
|
|
포인터와 구조체의 차이점은 뭐죠? (아직도 이해가 안되서 ^^;) |
|
|
지상현 2006-05-21 PM 5:30:21 |
|
|
|
구조체는 쉽게 생각해서 변수가 하나가 아니라 여러 개가 하나로 묶여있는 큰 덩어리예요.
그래서 구조체는 일반적으로 크기가 크기 때문에 포인터를 이용해서 간접적으로 접근합니다. 일일히 인자로 넘기면 매번 그만큼 메모리 복사를 해야 하니까요~~ |
|
|
박종훈 2006-05-21 PM 5:32:31 |
|
|
|
아.. 그렇군요 ^^ |
|
|
지상현 2006-09-26 AM 4:02:10 |
|
|
|
정정
C에서의 문자열 형식 LPTSTR, LPCTSTR 에 붙어있는 'T'에 대해서
여기서 T는 NULL로 끝나는 문자열이라고 설명했는데, 원래 C에서 문자열은 모두 NULL로 끝납니다.
여기에 붙은 T는 Translate 의 약자 같습니다.
즉, T가 들어있으면 컴파일 할 때 환경이 ANSI 냐 UNICODE 냐에 따라 자동으로 Ansi나 Unicode가 될 수 있는 문자열이란 뜻입니다.
붙어있지 않으면 항상 Ansi 문자열이죠. |
|
|
지우개 Expert 3.0 제작자 : 천호성 님 [LINK] |
|
|
|
대박로또2005 제작자 : 최재일 님 [LINK] |
|
|
1 | 박종훈 님 | 15292 점 | |
2 | 지상현 님 | 8809 점 | |
3 | 손상진 님 | 7388 점 | |
4 | 권선중 님 | 6060 점 | |
5 | 이진백 님 | 5174 점 | |
|
|
|
가입일 | 닉네임 |
05/31 | 김동률 |
03/31 | 홍형기 |
09/01 | o00pp99oo |
12/27 | 이재민 |
11/20 | 이희철 |
|
|
|
|
. |
. |
. |
|