6

私はこのようなイベント構造体を持っています

typedef struct {
    void* fn;
    void* param;
} event;

構造体の一部としてポインタでこの関数を呼び出すにはどうすればよいですか。たとえば、これらは機能しません。

event->(*function)();
event->function();
(*event->function)();

追加の void* パラメータを使用する場合と使用しない場合の両方で関数呼び出しを行う方法を知りたいです。私はもともとこのリンクを参照として使用していました:

http://www.cprogramming.com/tutorial/function-pointers.html

以前にこれらの関数ポインターを使用したことがありますが、構文を正しくするのに問題があります。

4

4 に答える 4

1

eventオブジェクトや式ではなく、typeです。構造体型のメンバーにはアクセスできず、構造体型のオブジェクトにのみアクセスできます。

与えられた:

typedef struct {
    void* fn;
    void* param;
} event;

type のオブジェクトがevent必要であり、そのメンバーに値を割り当てる必要があります。

あなたの質問ではfn、メンバー名として を使用していますが、 という名前を参照していますfunction。ここでは、それらは同じものであると仮定し、それfnは何らかの機能を指しているはずです。

関数ポインターを移植可能に格納することはできませんvoid*。多くの、おそらくほとんどの実装では、それを回避できますが、言語によって保証されていません。(関数ポインタがデータ ポインタよりも大きく、関数ポインタを変換するとvoid*情報が失われるシステムがあります。) 一方、すべてのポインタから関数への型は相互に変換可能であり、往復変換が保証されます。元のポインター値を提供します。

引数を取り、結果を返さないfn関数を指し示す必要があると仮定します (多くの情報を提供しなかったため、ここでは多くの仮定を行っています) 。void*それからaを作るparamvoid*は理にかなっています。その仮定との一貫性を保つために、型定義を変更できます。

typedef struct {
    void (*fn)(void*);
    void *param;
} event;

(void (*fn)(void*);構文は完全には明らかではありません。私はcdeclそれを構築していました。)

これで、 type のオブジェクトを定義できますevent:

event e = { some_func, NULL };

some_func次のように、どこかで定義する必要があります

void some_func(void *param { /* ... */ }

または同等のもの。eventこれで、オブジェクトを介して間接的にその関数を呼び出すことができますe:

e.fn(e.param);

または、へのポインターを持っている方が便利な場合event:

event *ptr = malloc(sizeof *ptr);
if (event == NULL) {
    /* error handling here */
}
ptr->fn = some_func;
ptr->param = NULL;

また、ポインターへのポインターと、それが指すオブジェクトにevent含まれる関数ポインターの両方で間接化を使用できます。event

ptr->fn(ptr->param);

達成しようとしていることに応じてfn、さまざまなタイプの関数を指すことができます。それを行う場合は、(明示的なキャストを使用して) 変換するか、それを介して呼び出す前に、それが指す関数の実際の型に変換する必要があります。異なる型の関数ポインターをやみくもに混在させることはできません。その場合、結果はコンパイル時エラーまたは実行時の未定義の動作になります。(パラメーターなしで結果を返さない関数へのポインター) を「ジェネリック」関数ポインター型として使用できますが、必要な型への変換とは異なり、明示的である必要があります。)e.fnptr->fnvoid (*)(void)void*

追加のパラメーターを使用する場合と使用しない場合の両方で関数呼び出しを行う方法を知りたいですvoid*

引数なしで関数を呼び出すには、単に()関数呼び出しで使用します。ただし、特定の関数については、パラメーターを指定して呼び出すかどうかを選択することはできません。呼び出しは定義と一致する必要があります。(おそらく のような可変引数関数を除きprintfますが、それでも正しい型の関数ポインタが必要であり、引数なしで可変引数関数を呼び出すことはできません。)

于 2013-09-19T18:00:16.680 に答える