2013-03-11 20 views
18

呼び出す関数の名前を表示したいと思います。ここに私のコード関数名を文字列として呼び出す

void (*tabFtPtr [nbExo])(); // Array of function pointers 
int i; 
for (i = 0; i < nbExo; ++i) 
{ 
    printf ("%d - %s", i, __function__); 
} 

それは私が好きなものとはかなり近いですので、私はexempleとして__function__を使用しているが、私はtabFtPtr [nbExo]が指す関数の名前を表示したいです。

ありがとうございました:)

+1

http://stackoverflow.com/q/679021/139010 –

+0

@ C++バージョンは、これを行うための標準的な方法はありません。どのコンパイラを使用していますか? –

+3

Cで関数のポインタから関数の名前を取得する方法http://stackoverflow.com/questions/351134/how-to-get-functions-name-from-functions-pointer-in-c – zzk

答えて

19

C99規格以降のCコンパイラが必要です。あなたが求めているのは、__func__という定義済みの識別子があります。

void func (void) 
{ 
    printf("%s", __func__); 
} 

編集:

好奇心の参照として、Cの標準6.4.2.2は、上記の明示的に書かれているかのようにまったく同じであることを指示:

void func (void) 
{ 
    static const char f [] = "func"; // where func is the function's name 
    printf("%s", f); 
} 

編集2:

したがって、関数ポインタで名前を取得するには、次のようなものを作成します。

const char* func (bool whoami, ...) 
{ 
    const char* result; 

    if(whoami) 
    { 
    result = __func__; 
    } 
    else 
    { 
    do_work(); 
    result = NULL; 
    } 

    return result; 
} 

int main() 
{ 
    typedef const char*(*func_t)(bool x, ...); 
    func_t function [N] = ...; // array of func pointers 

    for(int i=0; i<N; i++) 
    { 
    printf("%s", function[i](true, ...); 
    } 
} 
+0

関数ポインタからその文字列を取得することはできませんが、できますか? –

+0

@CarlNorum関数を呼び出すだけです。関数は何らかの形で__func__識別子を統合する必要があります。 – Lundin

+2

これがOPの質問とどのように統合できるのかは本当にわかりません。それだけです。彼は関数を呼びたくないようで、実行時に名前を取得するだけです。 –

1

私はこれがあなたの望むものかどうかはわかりませんが、このようなことをすることができます。関数名とアドレスを保持するための構造、ファイルスコープで関数の配列を宣言:

#define FNUM 3 

struct fnc { 
    void *addr; 
    char name[32]; 
}; 

void (*f[FNUM])(); 
struct fnc fnames[FNUM]; 

は、例えば、関数名が手動でコード内でこれらを初期化

fnames[0] = (struct fnc){foo1, "foo1"}; // function address + its name 
    fnames[1] = (struct fnc){foo2, "foo2"}; 
    fnames[2] = (struct fnc){foo3, "foo3"}; 

配列を検索する関数を作成します。

char *getfname(void *p) 
{ 
     for (int i = 0; i < FNUM; i++) { 
       if (fnames[i].addr == p) 
         return fnames[i].name; 
     } 
     return NULL; 
} 

私はこれを簡単にテストしました。配列をmainに初期化し、foo1()と呼んでいます。ここに私の関数はだ、と出力:

void foo1(void) 
{ 
    printf("The pointer of the current function is %p\n", getfnp(__func__)); 
    printf("The name of this function is %s\n", getfname(getfnp(__func__))); 
    printf("The name of the function at pointer f[2] (%p) is '%s'\n", f[2], 
     getfname(f[2]));  
} 

The pointer of the current function is 0x400715 
The name of this function is foo1 
The name of the function at pointer f[2] (0x40078c) is 'foo3' 
より一般

または、:

void foo2(void) 
{ 
    for (int i = 0; i < FNUM; i++) { 
     printf("Function f[%d] is called '%s'\n", i, getfname(f[i])); 
    } 
} 

Function f[0] is called 'foo1' 
Function f[1] is called 'foo2' 
Function f[2] is called 'foo3' 
+0

パフォーマンスのために、これは機能に追加のオーバーヘッドを追加しないので、おそらくより良い解決策です。 –

関連する問題