C :: typedef으로 함수 포인터를…

Dll Injection으로 Brute Force를 하려고 공부하던 차에 함수 포인터를 활용하는 방법을 알게 되었습니다. 일반적으로 C 언어는 절차 지향 언어, 함수 지향 언어라고 알려져 있어서 C++의 클래스 구현이 안 된다고 배웁니다만, 이 함수 포인터를 이용하면 충분히 클래스를 구현할 수 있을 것 같습니다. 실제로 커널 등의 여러 소프트웨어에서 이 방법을 쓰는 것 같구요.

함수 포인터를 선언하려면 우선 typedef으로 함수의 형태를 만들어줘야 합니다.

typedef int (*STRCMP)(char*, char*);


위 코드를 예로 들어보겠습니다. 이미 눈치 채셨겠지만, 이것은 strcmp() 함수의 포인터형을 정의하는 코드입니다. 먼저 typedef 다음에 나오는 int는 함수의 반환값을 의미합니다. 이것을 char*로 고치면 이 함수의 반환값은 char* 형이라는 것이겠죠? 그리고 (*STRCMP)가 함수 포인터입니다. 앞 쪽의 *를 보시면 감 잡으시겠죠? 마지막으로 뒷 쪽의 (char*, char*)는 함수에 들어갈 인자값입니다.

STRCMP my_strcmp = (STRCMP)strcmp;


함수 포인터를 정의하는 방법은 일반적으로 포인터를 정의하는 것과 같습니다. 함수 포인터형을 기술하고 뒤에는 함수의 이름을, 그런 다음에 캐스팅을 하여서 원래의 함수의 포인터를 넘기는 것이죠. 저기서 strcmp 대신 실제 메모리 주소를 적어도 똑같이 동작합니다. 원래는 메모리 주소를 적는 것이겠지만, 컴파일러에 의해서 맵핑되는 것이니까요.

실제 코드를 작성해볼까요?

#include <stdio.h>
#include <string.h>

typedef int (*STRCMP)(char*, char*);

int main (void)
{
    STRCMP my_strcmp = (STRCMP)strcmp;
    int value = my_strcmp ("a", "b");
    printf ("return value: %d\n", value);
    return 0;
}


이런 코드를 만들어 작성해보았습니다. 주의해야 할 점은 typedef로 정의되는 함수 포인터형의 형태와 실제 함수의 형태가 같아야 한다는 것입니다. 내부야 어떻게 되어있는지 몰라도, 반환값과 인자값은 형태가 같아야 정상적으로 동작하죠.

위 코드의 결과가 어떻게 나올까요? 컴파일러는 제대로 될까요? 결과는 제대로 나올까요? 아래를 조시면 모든 게 정상적으로 되는 것을 확인할 수 있습니다.

사용자 삽입 이미지
이로서 C로도 객체 지향적인 설계가 가능하겠죠?

Similar Posts

  • GTK+ :: C언어의 간편한 GUI 툴킷

    누군가가 그러더군요. 언어는 단지 도구일 뿐이고, 필요에 의해 쓰일 뿐이다. 저 말처럼 C언어를 익히니까 GUI 툴킷도 배우고 싶어졌습니다. 그래서 시작한 게 GTK+입니다. GTK+는 C언어를 기반으로 하는 GUI 툴킷입니다. 알아보니까 많이 쓰인다는 QT는 C++를 배워야 한다고 해서요. 배우다 보니까 여러 가지로 신기합니다. 그리고 재미있구요. 위 그림같은 창 하나 달랑 띄우는데도 코드가 여러 줄입니다. 그래도 이 정도면…

  • 우분투에서 듀얼 모니터 설정하기 (NVIDIA) + AWN 만져주기

    예전부터 작업을 할 때 문서와 편집기를 번갈아 가면서 띄우는 게 정말 불편해서 상당한 삽질 끝에 듀얼 모니터를 완성했습니다. 이 글은 저 말고도 원하는 분들을 위해 제가 듀얼 모니터를 설정한 방법을 쓴 글입니다. 여기서는 ATI 제품은 논외로 하겠구요. 페도라 11에서 아마 ATI가 제법 지원될 듯 한데, 우분투는 아직 길이 먼 듯 싶네요. NVIDIA 제품은 자체 설정…

  • 리눅스(우분투)에서 부경대학교 무선랜 접속하기

    이 글은 부경대학교 무선랜을 리눅스(Ubuntu 10.04 기준)에서 접속하는 방법에 대하여 작성되었습니다. 무선랜 활용 TIP :: http://www.pknu.ac.kr/files/wirelesslan/wirelesslan_guide.pdf자주하는 질문(FAQ) :: http://www.pknu.ac.kr/files/wirelesslan/wirelesslan_faq.pdf 단계 1 “시스템 -> 기본설정 -> 네트워크 연결” 실행 단계 2 “무선” 탭 선택 -> “추가” 버튼 클릭 단계 3 연결 이름에 “PKNU-WLAN” 입력 -> “무선” 탭에서 SSID 값에 “PKNU-WLAN” 입력 단계 4 “무선 보안” 탭에서…

  • C :: 0xE0 == 224 ?

    어느 한 분이 게시판에 질문을 올리셨습니다. 소코반 소스중에 일부분입니다. int ch; ch = getch(); //키 입력 if( ch==0xE0 ) { //실행 } 0xE0 은 십진수로 224입니다. 그러면 ch==224 랑 같으면 실행 된다는 말인가요 ㅡ.ㅡ? 『혼자 연구하는 C/C++』에 나오는 한 예제에 대한 질문이었습니다. C에서는 문자형으로 char가 사용됩니다. char는 1byte 자료형으로 -128~127의 값을 가집니다. 그럼 여기서부터 문제가…

  • imagEmail, 간략한 기획

    비주얼 베이직으로 만들었던 hisAlpha Image를 C 언어를 이용하여 리눅스용으로 다시 만들려고 합니다.  리눅스용이라고는 하나, 윈도우나 OS X용으로도 쉽게 포팅될 듯합니다. hiaAlpha Image는 일종의 프로토타입인 것이죠. 사실, 강분도 님의 권유가 아니었으면 그냥 묻혔을겁니다. ㅋ 아래는 간략한 기획입니다. 기능 이메일 주소를 이미지로 만듬. 15종의 메일서버 지원. 개발환경 환경: 리눅스 (Ubuntu 8.10, i386) 언어 및 툴킷 : C,…

  • C :: 1byte씩 메모리 읽기

    Shinnara 님이 알려주신 1byte씩 메모리를 읽는 방법입니다. 스택이나 정적메모리 영역 등에 이용할 수 있겠네요. unsigned char에 대해서는 거들떠 보지도 않았는데 이번 기회로 참 유용하다는 걸 알게되었습니다. ptr = (unsigned char *) &fNumber; 이 부분에 대해서는 지난 글에서 설명했었지요. 차이라고는 unsigned * 대신에 unsigned char *을 사용함으로써 4byte가 아닌 1byte씩 끊어 읽을 수 있다는 것입니다. 아래…

0 Comments

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다