2009-07-03 17 views
8

私は組み込みOSの例外処理を実装しようとしていますが、適切なハンドラを選択するためにスローされた "例外"の型を検出する方法には悩まされています。C++の最も単純なRTTI実装は何ですか?

例外処理の保存と復元のコンテキスト部分は既に実行されていますが、スローされた '例外'の型を検出できないため、特定のハンドルを持つことはできません。 C++の標準的なRTTIの実装は他のライブラリにも依存しており、そのため私は現在それを利用できないと考えています。

私のターゲットが組み込みシステムであり、そのためにたくさんのコードを作成することはできないと考えていますが、「実行時のタイプ情報」の最小実装は何ですか?

- 編集 -

私は、コンパイラに取り組んでいないよ、それはIA32-Gの++です。

+1

コンパイラや言語ランタイムを記述したり変更したりしていますか、それとも正確にどこに収まるでしょうか?もう少し文脈がいい。 – jalf

+0

メモリが限られている場合は、RTTIを有効にしたり、例外を使用したりしないでください。代わりのアプローチを考えてみてください。 –

+0

例外がスローされた場合、何らかの方法でthrow nustが例外の型情報をエンコードしているため、なぜ「代替」メソッドが必要なのかわかりません。 jalfが言ったように、あなたが実際にやろうとしていることについてもっと多くの情報を与えてください。 –

答えて

11

組み込み環境で作業している場合、おそらくごくわずかな解決策が優先され、コンパイラーに関する非標準または移植不可能な事実を利用できます。

クラスがポリモーフィック(それ自身の仮想関数が少なくとも1つあります)がC++であれば、その中にvtableへのポインタがある可能性があります。 vtableポインタがメモリ内のオブジェクトのレイアウトの先頭に表示されることがあります。

これは多くのコンパイラに当てはまりますが、これはC++ ABI-a related SO question hereを使用するコンパイラに当てはまります。

もしそうなら、あなたこのようなvtableのに取得することができるかもしれない:

void *get_vtable(void *obj) 
{ 
    return *(reinterpret_cast<void **>(obj)); 
} 

その後、あなたは、彼らは同じ型を指すかどうかを確認するために、2つのポインタ・ツー・オブジェクトのvtableをを比較することができますオブジェクトの。

だから、(基本的にされてキャッチするものです)「タイプのスイッチは、」このような何かをするだろう:

P p; 
Q q; 
if (get_vtable(caught) == get_vtable(&p)) 
{ 
    // it's a P... 
} 
else if (get_vtable(caught) == get_vtable(&q)) 
{ 
    // it's a Q... 
} 

あなたはCATCHマクロでそのパターンを隠すことができます。

重要なポイント - あなたはベースからクラスを派生ますが、派生クラスは、任意の仮想関数をオーバーライドしたり、任意の新しい仮想関数を追加しない場合、コンパイラが考えられる派生クラスの基本クラスのvtableのを再利用することができます。これは、2つの例外タイプを区別するために、それらがそれぞれ独自のvtableを持つことを保証するために、仮想関数をオーバーライドする必要があることを意味します。

これは、例外処理に関係する部分のごくわずかです。スタックを巻き戻すという小さな問題もあります!ハンドラにジャンプするときは、スタック上のすべてのオブジェクトのデストラクタを呼び出す必要があります。 setjmp/longjmpを実行するだけの問題ではありません。

+0

最初のコードで 'ptr'を取得する方法を表示できますか?そして私は 'obj'の役割も理解していませんでした。 – freitass

+0

申し訳ありませんが、それはタイプミスでした。これは単なる多態型のオブジェクトへのポインタです。 –

2

私が考えることができる最も単純なRTTIは、純粋な仮想 "GetType()"関数を持つ共通の基底からすべてのクラスを派生させることです。いずれかの文字列を返すか、その中のすべての型を持つ巨大なenumを作成してください。非常にシンプルで速く、メモリオーバーヘッドが少ない。しかし、特に柔軟性はありません。

+0

もちろん、仮想関数が存在するためには、ある種の仮想関数ポインタテーブルを使用している可能性があります。何とかrttiのために使用することができます... – gimpf

+0

巨大なenumの方法より多くの関与;) – Goz

+0

これらのVTablesを見つけることは、あまりにもクロスプラットフォームを少しタッドを追加する必要があります血まみいなハードワーク。 – Goz

関連する問題