0

編集: コールバック テンプレートに逆引用符を追加しました。インターフェイスは、アスタリスクを単なるアスタリスクとしてではなく、マークダウン インジケーターとして読み取っていました。

私が書いている Windows DLL/Linux SO では、ユーザー アプリにコールバック関数を登録する方法を提供します。よく働く。コールバックのプロトタイプは次のようになります(void)(*callback)(void*);

ドキュメントを書いているときにパラノイアに襲われ、登録されたアドレスが有効かどうかを知る良い方法がないことに気付きました。唯一のフィードバックは、クラッシュするか、try/catch 内でコールバックを呼び出すことです。

コールバックが存在せず、誰が何を実行したかを知っている場合、どの例外がスローされるかわかりません。「nowhere」への呼び出しが、クラッシュの代わりに例外を生成するのに十分なほど回復できるかどうかさえ、本当に確信が持てません。

はい、ユーザーの問題であることはわかっています。思慮深くなり、ユーザーが自分のバグを理解できるようにするだけです。

では、これはどのような例外をスローするでしょうか? Windows と Linux の回答が異なる場合は、回答してください。

または、欠落している関数を検出するために例外キャッチを使用することなく、これにアプローチするより良い方法はありますか?

4

5 に答える 5

6

回復する方法はありません。同様に、コールバックに のような行が含まれている場合は回復できません*(int*)(0x1234) = 5;。それと一緒に暮らすだけです。

C++ ライブラリ開発者は、何もクラッシュしないようにする仕事をしているわけではありません。文書化された方法で使用された場合に約束することを実行するコードを提供するだけです。

于 2013-04-10T13:03:53.327 に答える
3

トピックから少し外れますが、 の形式のコールバックvoid(*)()、つまり引数を 0 とるコールバックはあまり役に立ちません。便利な C スタイルのコールバックは、ユーザー指定の引数を受け入れるため、ユーザーはコールバックに対応する状態を見つけることができます。例えば:

typedef void callback_fn(void* user_arg);

callback_id register_callback(callback_fn* callback, void* user_arg);
void unregister_callback(callback_id);

コールバックのユーザーがなければuser_arg、コールバック関数に対応する状態を格納するためにグローバル変数を使用する必要があります。

于 2013-04-10T13:06:15.930 に答える
2

あなたが説明する状況はかなりありそうもないです。私はそのような取り扱いをどこでも見たことがありません。プログラムがクラッシュし、ユーザーを台無しにするだけです。

ただし、失敗の根本原因 (間違ったアドレスの割り当て) とその症状 (無効なアドレスへの呼び出し) が互いに遠く離れているため、特定するのが非常に難しい可能性があるため、あなたの懸念は有効です。

ここでアドバイスできるのは、「すばやく大声で失敗する」ことだけです。たとえば、コールバックが割り当てられるたびにコールバックのテスト呼び出しを行うことができます。これは依然としてクラッシュにつながりますが、スタック トレースで、ユーザーはすべてがどこから始まったかを確認できます。

繰り返しますが、これは通常の図書館ユーザーが期待するものではありません...

于 2013-04-10T13:08:01.777 に答える
1

私がここで答えたように:

インスタンスが破損しているかどうかをテストする方法は? (まったく別のタイプの質問ですが、同じことが当てはまります)

ポインターが「認識できない NULL または同様のもの」である場合、それが有効かどうかをコードで判断する方法はありません。

try/catch「コードの実行に失敗してもスローにならない」ため、 を使用して失敗をキャプチャすることもできません。

これは「プログラマーのエラー」なので、大きな問題ではないと思います。とにかく、プログラマーは自分のコードで好きなことをすることができるので、追加するメカニズムが何であれ、何らかの方法で回避することが可能になります。

于 2013-04-10T13:05:26.050 に答える