[질문] 함수 포인터 사용에 관해 궁금한 게 있어요

hados의 이미지

현재 임베디드 관련 개발 키트를 구매하여 그 소스를 받아서 분석을 하다가 함수 포인터와 관련해서 질문이 생겨서 올리게 되었습니다.

소스는 약 20개 정도의 *.h, *.c 파일로 구성되어 있으며, 딱 1개의 소스 파일(r.c)만 libr.a 라는 아카이브 파일 형태로 제공되었습니다.

(해당 파일의 소스는 공개할 수 없답니다)

그런데 바로 그 libr.a 라는 파일에 정의되어 있는 함수(rInit)를 호출할 때 인자로 함수 포인터(fptr)를 넘기더군요.

(참고로 분석하던 소스 전체에서 함수 포인터를 쓴 곳은 여기밖에 없습니다)

그래서 왜 저 부분만 함수 포인터로 함수를 넘길까? 고민해 봤는데 잘 모르겠네요 ㅠㅠ

참고로 위에서 언급했다 시피 아래의 r.c 라는 파일은 주어지지 않은 상태라고 가정합니다.
r.h, libr.a는 주어지지만 r.c 라는 소스 파일은 주어지지 않은 상황입니다.

r.h

void rInit(void (*f1)());

r.c - 주어지지 않은 소스 파일이지만 이렇게 생겼다고 가정

void rInit(void (*f1)())
{
        printf("rInit\n");
f1();
}

n.h

void nInit();

n.c

void nInit()
{
        printf("nInit\n");
}

main.c

#include "r.h"
#include "n.h"
...
int main()
{
        void * fptr = nInit;
        rInit(fptr);
        return 0;
}

위의 파일들을 아래와 같이 build 합니다.

gcc -c r.c n.c main.c
ar r libr.a r.o
gcc -o main main.o n.o -L. -lr

위에서 보면 r.c 에서 n.h 파일을 include 해서, rInit() 함수 안에서 nInit() 함수를 호출해도 될 듯 한데,

굳이 nInit() 함수의 function pointer를 rInit() 함수의 인자로 넘겨준 이유가 무엇인지 궁금합니다. ^^

왜 꼭 함수 포인터를 사용했을까? 라고 생각을 하니 어떤 특별한 이유가 있을 것도 같은데 정확히는 모르겠습니다.

혹시 libr.a 의 소스 공개를 꺼려하던 것과 관련이 있을까요?

어차피 libr.a의 소스를 주지 않았다면, 함수 포인터를 쓰던지 안 쓰던지 간에 별 상관 없을거 같은데 말이지요.

그럼 고수님들께 미리 감사드리면서...열심히 공부하겠습니다. ㅠㅠ

chadr의 이미지

말씀대로 r.c에서 n.h를 include할수 없기 때문입니다.

r.c의 소스가 주어지지 않았기 때문이지요.. 그렇기 때문에 질문자님께서 작성하신 함수인 void nInit()를 r.c에서 같이 컴파일하여 링크할수 없습니다.

대부분 저렇게 함수포인터를 넘겨주는 이유는 해당 라이브러리에서 어떠한 기능을 사용하는 프로그래머가 직접 커스터마이징을 하게 하거나 해당 라이브러리가 컴파일되는 시점에서 특정기능을 정의 할수 없는 상황에 대해서 저런식의 구성을 하기도 합니다.

간단하게 예를들면 플러그인 같은 경우가 예가 되겠습니다.
-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.

-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.

hados의 이미지

제가 설명을 자세히 못 했군요. ^^

위에서 예로 든 코드는 모두 개발 키트에 구현되어 있는 라이브러리 입니다.

제가 따로 추가한 것이 아니라 개발 키트 소스 분석하다 보니 저런 코드가 있어서 왜 저럴까? 고민하는 중입니다.

(물론 r.c 는 아주 간단하게나마 저렇게 생겼을 것이다...라고 제가 가정한 것일 뿐입니다)

위의 저 소스를 개발한 개발자는 r.c 라는 파일도 가지고 있을 것입니다. 그렇다면 n.h 를 include 를 해서 컴파일 할 수도 있을텐데

굳이 함수포인터를 써서 구현한 이유가 무엇일까?

이것이 궁금한 겁니다.

설명을 제대로 못해서 지송... ioi

chadr의 이미지

글쎄요.. 그건 저 라이브러리를 개발한 사람한테 물어봐야할거 같습니다. ㅎㅎ
아니면 그 소스가 있거나요..ㅎㅎ

한가지 그냥 추측하건데..
나중에 확장성을 위해서 저렇게 설계를 했을지도 모른다는 생각도 드는군요..
나중에 함수포인터로 넣은 함수를 다른걸로 대체할려고 했을때 단지 변경된 함수 포인터만 넣어주고 재컴파일을 하면 될테니까요..
-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.

-------------------------------------------------------------------------------
It's better to appear stupid and ask question than to be silent and remain stupid.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.