はじめに
このプロジェクトでは、C 言語でコールバック関数を実装する方法を学びます。コールバック関数は、C 言語のプログラミングにおいて、特に Linux システム開発のコンテキストで一般的に使用される強力な技術です。
👀 予習
$ gcc test_callback.c callback.c -o test_callback
$./test_callback
Alarm1:0
Alarm2:1
Alarm3:2
🎯 タスク
このプロジェクトでは、以下のことを学びます。
- C 言語でコールバック関数を定義および使用する方法
- コールバック関数を使用してアラームを登録およびトリガーする方法
- コールバック関数の実装におけるエッジケースとエラーを処理する方法
🏆 成果
このプロジェクトを完了すると、以下のことができるようになります。
- コールバック関数の概念とその C 言語プログラミングにおける使用方法を理解する
- コールバックベースのアラームシステムを実装し、アラームの登録とトリガーを含める
- コールバック関数における潜在的な問題を処理するための堅牢で防御的なコードを書く
- イベント駆動型システムや非同期操作など、C 言語プログラミングの他の分野においてコールバック関数の知識を適用する
コールバック関数を理解する
このステップでは、C 言語におけるコールバック関数の概念と、Linux C プログラム開発においてそれがどのように使用されるかを学びます。
コールバック関数は、関数を別の関数に引数として渡す方法であり、その後、渡された関数を呼び出すことができます。これは、より柔軟でモジュール化されたコードを可能にする強力な技術です。
callback.cファイルに提供されているコードでは、コールバック関数がアラームシステムを実装するために使用されています。alarm構造体はアラームを表し、register_alarm関数はアラームを登録するために使用されます。その後、hit_alarm関数が登録されたアラームをトリガーするために使用されます。
欠陥を特定して修正する
では、callback.cファイルに提供されているコードを見て、欠陥を修正しましょう。
- セグメンテーションフォールト:これはおそらく
alarm_listが正しく埋められていないか、不正なメモリアクセスを引き起こすアクセス方法であるためです。 register_alarmにおける不適切なインデックス処理:index変数はregister_alarmに局所的で、関数が呼び出されるたびに 0 に再初期化されます。これにより、すべてのアラームがインデックス 1 に登録され、互いに上書きされます。
callback.cファイルを以下のように更新します。
#include "callback.h"
alarm alarm_list[MAX_ALARMS];
int current_index = 0; // グローバルなインデックストラッカー
void register_alarm(alarm a) {
if (current_index < MAX_ALARMS) {
alarm_list[current_index] = a;
current_index++;
}
// 登録されたアラームの数が MAX_ALARMS を超えた場合、何もしない(エラーを報告しない)
}
int hit_alarm(int index) {
if (index < 0 || index >= MAX_ALARMS ||!alarm_list[index])
return 1;
(*alarm_list[index])(index);
return 0;
}
主な変更点は以下の通りです。
- アラーム登録のための現在のインデックスを追跡するためのグローバルな
current_index変数を追加しました。 register_alarmでは、アラームを登録する前にcurrent_indexがMAX_ALARMS未満であることを確認します。登録されたアラームの数がMAX_ALARMSを超えた場合、エラーを報告せずにそのまま続行します。hit_alarmでは、インデックスが有効な範囲内であり、そのインデックスに実際にアラームが登録されていることを確認するための追加のチェックを行います。そうでない場合は、アラームがトリガーされなかったことを示すために 1 を返します。
コールバック関数をテストする
callback.cファイルの欠陥を修正したので、提供されているtest_callback.cプログラムを実行してコールバック関数をテストしましょう。
プログラムをコンパイルします。
gcc test_callback.c callback.c -o test_callback
プログラムを実行します。
./test_callback
出力:
Alarm1:0
Alarm2:1
Alarm3:2
現在、出力は予想される出力と一致し、プログラムはセグメンテーションフォールトやその他のエラーなしに実行されるはずです。
おめでとうございます!あなたはコールバック関数の実装を正常にデバッグして修正しました。
まとめ
おめでとうございます!このプロジェクトを完了しました。あなたのスキルを向上させるために、LabEx でさらに多くの実験を行って練習してください。



