2011-08-03 13 views
8

2つのプロジェクトがあるとします。 1つはアプリケーションであり、もう1つはこのアプリケーション以外で使用できる共通の再利用可能なコードを含む共有ライブラリです。共有ライブラリ境界を中心としたC++インターフェイスの設計

私のアプリケーションはSTLを使用し、共有ライブラリはSTLも使用します。ここでの最初の問題は、共有ライブラリがSTLを使用していることです。アプリケーションに新しいバージョンのSTLをビルドしても、必要でないため共有ライブラリを再構築しないと、すぐに互換性の問題が発生します。

この問題を解決する私の最初の考えは、共有ライブラリクラスへのインターフェイスでSTLをまったく使用しないことです。私たちのライブラリに、文字列を受け取り、何かを行う関数があるとします。 、これはおそらく、STLの異なるバージョン間でOKになりますが、欠点は、我々はstd::stringから行っているということである文字列の場合

void DoStuffWithStrings(std::string const& str); 

void DoStuffWithStrings(char const* str); 

の代わりに:私のような関数プロトタイプを見てになるだろうchar*に戻り、std::stringに戻って、パフォーマンスの問題を引き起こすようです。

STL対応の生のタイプのボクシング/アンボッティングは推奨されていますか?私たちがstd::listにこれをしようとすると、これはさらに悪化します。なぜなら、何らかのO(n)または同様の操作をしなくても簡単に渡すことができることを知っている「生の型」は実際には存在しないからです。

このシナリオではどのようなデザインが最適ですか?それぞれの長所と短所は何ですか?

答えて

3

const char*の利点の1つは、あなたのライブラリもCから呼び出し可能であり、それゆえにCにもインタフェースする他の多くのラグであることです。これだけで非常に興味深いセールスポイントです。

しかし、両方のライブラリを作成して管理していて、それらがC++でのみ使用される場合(次の5年間)、すべてを変換するという面倒はありません。 std::stringは1つのことですが、std::vectorまたはstd::mapはうまく変換されません。それ以外に、あなたは別のSTL実装に何回移動しますか?そしてそのような場合には、共有ライブラリを再構築することを本当に「忘れる」ことになりますか?また、実際に必要であれば、後でCスタイルのラッパーを作成/生成することもできます。

結論(この問題についての私の経験に偏っている):Cが必要ない場合は、stlに行ってください。

+0

Cとの互換性は唯一の関心事ではなく、親指IMHOの非常に良いルールではありません。あなたが言うように、共有ライブラリが常にアプリケーションでビルドされることを保証するものではないが、Cによってまったく使用されない場合、互換性の問題を考慮する必要があります。 C++は(.NETやC#のようなものに比べて)非常に弱い共有ライブラリサポートを持っているので、要件にかかわらず、互換性が問題になることはありません。 'std :: vector'と' std :: map'では、どういうわけかそれらをユーザー型にマップすることができます。 –

+0

はい条件はもっと「Cを必要とせず、すべてのライブラリを制御できたら」のようになります。 – stijn

0

多くのA.P.I.および共有ライブラリはバージョン間の違いを避けるために関数の引数として "不透明"または汎用ポインタを使用します。

// this: 
int MyFunc(char* Param1, int Param2, bool Param3); 

// into this: 
struct MyParams 
{ 
    char* Param1; 
    int Param2; 
    bool Param3; 
} 

// "Params" its really "struct MyParams*" 
int MyFunc(void* Params); 

共有ライブラリ関数は、いくつかの引数を持っている場合、時には、彼らはポインタに置き換え、tahtは、配列や構造、あるいはクラスへのポインタであることが期待されます。

これは、C++を使用していても、多くのライブラリがプレーンCのように使用されているので、どのようにライブラリを操作するかによって異なります。

2

確かに、標準のC++ライブラリは、仮想テーブルレイアウトまたは名前のマングリングスキームと同じように、C++ ABIの一部と考えるべきです。さらに、ABIの互換性のない変更は、std :: vectorのレイアウトではなく、不明瞭なコーナーケースに影響を与える可能性が高くなります。つまり、C++ライブラリを作成する場合は、標準のC++クラスを自由に使用できます。

+0

vtablesと名前のマングリングスキームはどのような例で変更されますか?これらは、STLほどには変わらないようです。 –

+0

@Robert古いコンパイラバージョンにバグがあった場合や、新しいコンパイラバージョンが新しいバージョンの標準から新しい言語機能をサポートしている場合は、変更が必要になります。基本的には、標準ライブラリABIの変更にも同じ条件が適用されます。誰も標準ライブラリを互換性のない方法で変更するつもりはない。 – han

+0

たとえば、VS8からVS9にアップグレードすると、互換性が失われますか? –

1

ライブラリがアプリケーションとは異なるヒープを使用する場合、別の問題が発生することがあります。これが当てはまる場合、またはそうである可能性がある場合は、ライブラリが独自のメモリを所有/管理していることを確認してください。ライブラリーが異なるcライブラリー、したがって異なるmalloc/freeを使用し、したがって異なるヒープを使用する場合、複数のヒープが問題になる可能性があります。 http://msdn.microsoft.com/en-us/library/ms810466.aspx

関連する問題