void (*Task)()
実際には関数ポインタです。基本的には次のように言っています。「パラメータ名はTask
であり、これは戻り値を返す関数でありvoid
、(これはc ++ではなくcであるため)任意の数の引数を取ります。
したがって、次のように呼び出すことができます。
void my_task() {
/* do something */
}
TaskCreate(my_task);
もちろん、書くvoid my_task(void) {
のも安全でしょう。cをコーディングするとき、私は個人的に「パラメーターはありません」と明示的に言うことを好みます。
最後に、*(int*)((NewTCB->Stack) + (STACK_DEPTH-2)) = (int)Task;
いくつかのキャスト魔法をやっています。
それを分析しましょう:
(int)Task
は最初にに変換Task
されますint
(これは疑わしいですが、おそらく特定のアーキテクチャ/ OSには問題ありません。個人的には、long
安全のためにaを使用します)。
((NewTCB->Stack) + (STACK_DEPTH-2))
は、スタックNewTCB->Stack
内の場所へのポインタを取得するために、いくつかの簡単な計算を実行しているだけです。TCB
*(int*)
「これをに変換してから、int *
それが指す場所を区別(読み取りまたは書き込み)します。
これはもっと簡単に次のように書くことができます。
int f = (int)Task;
int s = ((NewTCB->Stack) + (STACK_DEPTH-2)); /* I don't know the type of `NewTCB->Stack`, so we'll pretend 'int' for now */
int *stack_ptr = (int*)s;
*stack_ptr = f;
これはおそらくもっと明確です。
フォローアップ:構文が少し混乱することがあるので、私がどのように関数ポインターを使用する傾向があるかを指摘したいと思います。そして、このアプローチは非常に役立つと思います。基本的に、私typedef
は関数ポインターのを作成し、代わりにそれを使用するのが好きです。代わりに、正しく理解する方がはるかに簡単だと思います。
例えば:
/* typedef func_t to be a pointer to a function taking no arguments and returning void */
typedef void (*func_t)(void);
じゃあ後で...
void CreateTask(func_t task) {
/* same work as your example, just a little easier to read */
}