23

私はCライブラリを作成した経験がありますが、そのようなライブラリを作成している間、グッドプラクティスを説明する正式なドキュメントを読んだことはありません。私の質問は主に2つのトピックに関係しています。

  1. バイナリ互換性を維持する方法は?(pImplイディオム、dポインターについて聞いたことがあります)
  2. 下位互換性を維持するインターフェイスを設計するにはどうすればよいですか?

私の研究からわかるバイナリ互換性の主な点は、pImplイディオムを使用してライブラリをバイナリ互換にすることができるということですが、構造を変更したり、新しいデータメンバーを追加したりすると、pImplを使用している場合でもバイナリ互換性に影響を与える可能性があります。また、バイナリ互換性を実際に壊すことなく、ライブラリに新しいメソッド/関数を追加する方法はありますか?これらを追加すると、ライブラリのサイズやレイアウトが変更され、互換性が失われると思います。

バイナリ互換性をチェックするツールはありますか?

私はすでにこれらの記事を読みました。他に閲覧できるドキュメントはありますか?

http://en.wikipedia.org/wiki/Opaque_pointer

http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C++

また、ライブラリインターフェイスの設計のコンテキストでメモリの所有権の問題を説明する記事があります。一般的な規則は何ですか?誰がどのくらいの期間メモリを所有し、誰がメモリの割り当てを解除する責任がありますか?

4

4 に答える 4

21

主な互換性の問題は次のとおりです。

  • 関数シグネチャ
  • ライブラリと呼び出し元の両方がアクセスするデータの形式
  • 呼び出し元がアクセスするライブラリ内のグローバル変数
  • ヘッダーのマクロ/インライン関数が原因で呼び出し元に到達するライブラリコード
  • #define/enum共有ヘッダーの定数値

したがって、私が提供できるガイドラインの最良のリストは次のとおりです。

  • パブリックインターフェイスの署名(リターン/引数タイプ)は絶対に変更しないでください。インターフェイスを拡張する必要がある場合は、代わりに、より多くの引数を取る新しい関数を追加します(dupvsdup2またはwaitvsを考えてくださいwaitpid)。
  • 可能な限り、完全にカプセル化された不透明(OPAQUE)オブジェクトへのポインターを使用し、パブリックヘッダーでそのような構造の定義を公開しないでください(不完全なstruct型にします)。
  • 構造体を共有したい場合は、呼び出し元がその構造体タイプの変数を宣言しないように調整し、代わりにライブラリ内の明示的なallocate/free関数を呼び出します。既存のメンバーのタイプを変更したり、既存のメンバーを削除したりしないでください。代わりに、構造の最後にのみ新しいメンバーを追加してください。
  • ライブラリ、期間からグローバル変数を公開しないでください。「コピーの再配置」を理解していない限り、理由を尋ねないのが最善です。ただそれをしないでください。
  • 永続的に保持される文書化された公開インターフェースを使用しない限り、ライブラリのパブリックヘッダーにインライン関数またはコードを含むマクロを配置しないでください。不透明(OPAQUE)データオブジェクトの内部を突くと、内部を変更するときに問題が発生します。
  • 既存の#define/enum定数の番号を付け直さないでください。以前に使用されていない値を持つ新しい定数のみを追加します。

これらのガイドラインに従えば、少なくとも95%はカバーされていると思います。

于 2011-08-27T21:12:10.627 に答える
4

ドキュメントに関しては、 UlrichDrepperによる共有ライブラリの書き方は必読です。

于 2011-08-29T05:28:28.727 に答える