STLコンテナとバイナリインターフェイスの互換性
-
28-10-2019 - |
質問
STLバイナリインターフェイス
複数のコンパイラとC ++のプラットフォームにわたって、STLオブジェクトの互換性のあるインターフェイスレイヤーに取り組んでいるかどうかを知りたいと思います。
目標は、STLタイプを一流または固有のデータ型としてサポートすることです。
一般的にテンプレートによって課される固有の設計制限はありますか?これは、バイナリ分布にSTLを使用することの大きな制限のようです。
理論 - おそらく答えは実用的です
Microsoftは.NETに努力しており、C ++ STLサポートが「ファーストクラス」であることを実際には気にしません。
オープンソースはバイナリのみの配信を宣伝したくないため、10の異なるバージョンの不一致ではなく、単一のコンパイラで物事を正しくすることに焦点を当てています。
これは、QTや他のライブラリでの私の経験によってサポートされているようです。通常、使用する環境にビルドを提供します。たとえば、QT 4.6およびVS2008。
参考文献:
解決
問題だと思います 先行性 理論:C ++はABI(アプリケーションバイナリインターフェイス)を指定しません。
実際、Cはそうではありませんが、cライブラリであるため、関数のコレクション(そしてグローバル変数である可能性があります)であるため、ABIは機能自体の名前です。プラットフォームに応じて、名前はどういうわけかマングルすることができますが、すべてのコンパイラがシステムcalssを配置できる必要があるため、すべてがオペレーティングシステムビルダーの同じコンベンションを使用することになります(Windows、 _cdecl
準備するだけです _
関数名に。
しかし、C ++には過負荷があるため、より複雑なマングリングスキームが必要です。今日のところ、コンパイラメーカーの間には、そのようなマングルがどのように行われなければならないかについての合意はありません。 C ++静的ライブラリをコンパイルし、別のコンパイラから来るC ++ OBJにリンクすることは技術的には不可能です。 DLLについても同じです。
また、コンパイラがコンパイルされた過負荷メンバー関数でも異なるため、実際にテンプレートの問題を実現する人はいません。
すべてのパラメトリックタイプのリダイレクトを導入し、ディスパッチテーブルを導入することで技術的には提供できますが、...これにより、テンプレートされた関数が仮想ベースの仮想関数とは異なる(コールディスパッチの点で)異なるため、テンプレートのパフォーマンスが似ています。クラシックなOOPディスパッチへ
現在、コンパイラメーカーの間には、すべてのメーカーが彼自身の最適化で持つことができるすべてのパフォーマンスの違いを犠牲にするため、共通の基準に同意することは関心がないようです。
他のヒント
C ++テンプレートは、コンパイル時間生成コードです。
つまり、テンプレートクラスを使用する場合は、ヘッダー(宣言)を含めて、コンパイラが必要なテンプレートクラスに適切なコードを生成できるようにする必要があります。
そのため、テンプレートをバイナリファイルに事前にコンパイルすることはできません。
他のライブラリがあなたに与えるものは、テンプレートされていない事前にコンパイルされた基本活動クラスです。
たとえば、C#ジェネリックは、DLLまたは実行可能ファイルの形でILコードにコンパイルされます。
ただし、ILコードは別のプログラミング言語と同様にするため、コンパイラは含まれているライブラリからジェネリック情報を読み取ることができます。
.NET ILコードは実行時に実際のバイナリコードにコンパイルされるため、実行時にコンパイラには、ジェネリックに適切なコードを生成するために必要なすべての定義があります。
複数のコンパイラとC ++のプラットフォームにわたって、STLオブジェクトの互換性のあるインターフェイスレイヤーに取り組んでいるかどうかを知りたいと思います。
はい、そうです。 (とりわけ)コンポーネントの境界全体にわたるSTL、ブースト、またはその他のC ++タイプのインスタンスへのバイナリセーフの「管理」参照を渡すために使用できる標準化されたインターフェイスの層に取り組んでいます。ライブラリ(「Vex」と呼ばれる)は、これらのインターフェイスと適切な工場の実装を提供し、人気のあるSTD ::またはBoost :: Typesを包み込み、ラップします。さらに、ライブラリはLINQのようなクエリ演算子を提供して、私が呼ぶものの内容をフィルタリングして操作します Range
と RangeSource
. 。図書館はまだ「公開」する準備ができていませんが、できるだけ早く「初期の「プレビュー」バージョンを公開するつもりです...
例:
com1
参照を渡します std::vector<uint32_t>
に com2
:
com1:
class Com2 : public ICom1 {
std::vector<int> mVector;
virtual void Com2::SendDataTo(ICom1* pI)
{
pI->ReceiveData(Vex::Query::From(mVector) | Vex::Query::ToInterface());
}
};
com2:
class Com2 : public ICom2 {
virtual void Com2::ReceiveData(Vex::Ranges::IRandomAccessRange<uint32_t>* pItf)
{
std::deque<uint32_t> tTmp;
// filter even numbers, reverse order and process data with STL or Boost algorithms
Vex::Query::From(pItf)
| Vex::Query::Where([](uint32_t _) -> { return _ % 2 == 0; })
| Vex::Query::Reverse
| Vex::ToStlSequence(std::back_inserter(tTmp));
// use tTmp...
}
};
Linq、boost.range、Any_iterator、d's rangesなど、さまざまな馴染みのある概念との関係を認識します。「vex」の基本的な意図の1つは、ホイールを再発明することではありません。クエリ用の砂糖。
乾杯、
ポール