2

STLバイナリインターフェイス

C++用の複数のコンパイラとプラットフォーム間でSTLオブジェクトの互換性のあるインターフェイスレイヤーに取り組んでいる人がいるかどうか知りたいです。

目標は、STLタイプをファーストクラスまたは組み込みのデータ型としてサポートすることです。

これを防ぐ一般的なテンプレートによって課せられる固有の設計上の制限はありますか?これは、バイナリ配布にSTLを使用する際の主な制限のようです。

理論-おそらく答えは実用的です

  1. Microsoftは.NETに力を入れており、C++STLサポートが「ファーストクラス」であることをあまり気にしていません。

  2. オープンソースは、バイナリのみの配布を促進することを望んでおらず、10の異なるバージョンの不一致ではなく、単一のコンパイラで問題を解決することに重点を置いています。

これは、Qtや他のライブラリでの私の経験によってサポートされているようです。これらは通常、使用する環境のビルドを提供します。たとえば、Qt4.6およびVS2008。

参照:

4

3 に答える 3

3

問題はあなたの理論に先行していると思います。C++はABI(アプリケーションバイナリインターフェイス)を指定していません。

実際、Cでさえそうではありませんが、Cライブラリであるため、関数の単なるコレクション(およびグローバル変数である可能性があります)であるABIは、関数自体の名前にすぎません。プラットフォームによっては、名前がなんらかの形で混乱する可能性がありますが、すべてのコンパイラがシステムcalsを配置できる必要があるため、すべてがオペレーティングシステムビルダーの同じ規則を使用することになります(Windowsでは、関数名の_cdecl前にaを付けるだけです。_

ただし、C ++にはオーバーロードがあるため、より複雑なマングリングスキームが必要です。今日のところ、そのようなマングリングをどのように行わなければならないかについて、コンパイラメーカー間で合意はありません。C ++静的ライブラリをコンパイルして、別のコンパイラからのC++OBJにリンクすることは技術的に不可能です。DLLについても同じです。

また、コンパイルされたオーバーロードされたメンバー関数でもコンパイラーはすべて異なるため、実際にテンプレートの問題を解決できる人は誰もいません。

技術的には、すべてのパラメトリックタイプにリダイレクトを導入し、ディスパッチテーブルを導入することで実現できますが、これにより、テンプレート関数は仮想ベースの仮想関数と(コールディスパッチに関して)違いがなくなり、テンプレートのパフォーマンスが類似するようになります。従来のOOPディスパッチに(コードの膨張を制限できますが...トレードオフは必ずしも明白ではありません)

現時点では、コンパイラメーカー間で共通の標準に同意することに関心はないようです。これは、すべてのメーカーが独自の最適化で持つ可能性のあるすべてのパフォーマンスの違いを犠牲にするためです。

于 2011-12-06T08:19:04.037 に答える
2

C ++テンプレートは、コンパイル時に生成されるコードです。
つまり、テンプレートクラスを使用する場合は、そのヘッダー(宣言)を含めて、コンパイラが必要なテンプレートクラスに適切なコードを生成できるようにする必要があります。

そのため、テンプレートをバイナリファイルにプリコンパイルすることはできません。

他のライブラリが提供するのは、テンプレート化されていないコンパイル済みの基本ユーティリティクラスです。

たとえば、C#ジェネリックは、dllまたは実行可能ファイルの形式でILコードにコンパイルされます。
ただし、ILコードは別のプログラミング言語とまったく同じであるため、コンパイラーは付属のライブラリーからジェネリックス情報を読み取ることができます。

.Net ILコードは実行時に実際のバイナリコードにコンパイルされるため、実行時のコンパイラには、ジェネリックに適切なコードを生成するためにILで必要なすべての定義があります。

于 2011-12-06T05:37:40.597 に答える
2

C++用の複数のコンパイラとプラットフォーム間でSTLオブジェクトの互換性のあるインターフェイスレイヤーに取り組んでいる人がいるかどうか知りたいです。

はい、そうです。私は、コンポーネントの境界を越えてSTL、Boost、またはその他のC ++タイプのインスタンスへのバイナリセーフな「マネージド」参照を渡すために(とりわけ)使用できる標準化されたインターフェイスのレイヤーに取り組んでいます。ライブラリ(「Vex」と呼ばれる)は、これらのインターフェースの実装に加えて、人気のあるstd::またはboost::タイプをラップおよびアンラップするための適切なファクトリを提供します。さらに、ライブラリはLINQのようなクエリ演算子を提供して、私が呼び出したものの内容をフィルタリングおよび操作しRangeますRangeSource。ライブラリはまだ「公開」する準備ができていませんが、できるだけ早く「プレビュー」バージョンを公開する予定です...

例:

com1std::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つは、車輪の再発明ではなく、そのインターフェイスレイヤーに加えて必要なインフラストラクチャと構文を追加するだけです。クエリ用の砂糖。

乾杯、

ポール

于 2011-12-06T08:41:44.240 に答える