2013-03-26 3 views
10

OpenCVのような十分に確立されたC++ライブラリで単一のクラスメソッドを追加または変更し、残りのライブラリを再利用するベストプラクティスコード、好ましくはlib形式です。ライブラリの残りの部分をそのまま維持しながらC++ライブラリを部分的に変更するためのベストプラクティス

私が知っている唯一の方法は、特定のライブラリ(OpenCVのコアライブラリと言う)にあるすべてのソースファイルとヘッダーファイルを現在のソースフォルダにコピーし、その1つの関数を修正し、残りのコード。理想的には、すべての現在の.libファイルをそのままリンクすることができますが、メソッドの実装が上書きする方法でこれらのlib内で定義されたクラスの新しいメソッドを定義する(または現在のメソッドを変更する)デフォルトのライブラリファイルの実装。

継承が常にオプションであるとは限りません。基本クラスには、継承された正しいクラスの実装に必要なプライベートメンバーが存在することがあるためです。

答えて

7

私はあなたが求めていることを達成するためのC++のきれいな方法を知らない。あなたが本当にやりたいことは(あなたがプライベートメソッドを使用したり変更したりする必要があることを考えると)、カプセル化に違反しています.C++言語はあなたにそれを許さないように設計されています。

いくつかのオプションが存在します

  • .libファイルには、単に.objファイルの集まりです。コンパイラツールチェーンには、.libにある.objファイルを追加、削除、および置換するためのコマンドラインプログラムが必要です。したがって、1つまたは2つの.objファイルを作成し、.libにマージすることができます。私はこの解決策が醜くて壊れやすいと思う。
  • ライブラリにはないし、すべきことがある場合は、その変更を行うために、ライブラリの作成者にパッチまたは機能要求を提出する可能性が常にあります。もちろん、これがまったく動作するのであれば、これには時間がかかることがあります。
  • @fatih_kが示唆しているように、フレンドクラスが機能するように変更を追加してください。 OpenCVに変更した場合は、ヘッダファイルにfriend行を追加するだけです。ライブラリのABIは変更されず、.libに触れる必要はありません。
  • あなたが自分で開発したソースコードと共に、OpenCVライブラリを修正し、ソースコードを追跡する必要があることを受け入れるだけで、自分で構築したソースコードとともにビルドすることが最も簡単な選択肢です。これは非常に一般的なアプローチであり、さまざまなパターンやテクニックが存在します。たとえば、Subversionのコンセプトはvendor branchesです。このアプローチは、より多くの設定作業ですが、長期的には最もクリーンです。
+0

優れたポイント。私は間違いなくこの記事を読んでたくさん学んだ。ありがとう。 – Bee

1

OpenCVはBSDのライセンスを受けているため、再公開する心配もありません。

いつでもプロキシデザインのパターンに従って、ライブラリの外部に新しいメソッドを追加してそこからライブラリに呼び出すことができます。つまり、OpenCVの独自のバージョンを維持して配布することについても心配する必要はありません。 There's more information about Proxy patterns on Wikiを起動してください。

+0

ありがとうございます。残念なことに、プロキシデザインはプライベートメンバーの問題へのアクセスを解決しません。具体的には、OpenCVのクラスの現在のメソッドを変更して、内部(時にはプライベート)メンバーを異なる方法で処理したいと考えています。プロキシは私に追加の前処理をさせてくれるようですが、実際のクラスの基本ロジックは同じままです。 – Bee

+0

ああ、申し訳ありませんが、プライベートメンバーのデータを変更しようとしていたことに気づいていませんでした。 –

2

ライブラリが既にコンパイルされている場合は、移植性が高く、きれいに実行できます。

プログラムが実行される特定のターゲットアーキテクチャが分かっている場合は、メソッドの独自のバージョンにjmp命令で説明されている指示に従って、メンバ関数へのポインタを得ることができます。メソッドが仮想の場合、vtableを変更できます。コンパイラ固有の知識が多く必要なため、移植性がありません。

ライブラリがダイナミックリンクアーカイブに含まれている場合は、アーカイブを抽出して、そのメソッドを独自のバージョンに置き換えて、アーカイブを再パックすることができます。

もう1つの方法は、クラスの宣言をヘッダーからコピーし、フレンド宣言を追加することです。また、ヘッダーファイルを含める前に#define private publicまたは#define private protectedを実行することもできます。これらはプライベートメンバーへのアクセスを提供します。

これらのいずれかを使用して、変更がライブラリのABIを変更しないように注意する必要があります。

+0

ありがとう!興味深くて役に立つアイデアですが、この特定の作業にはあまりにも多すぎます。 OpenCVはオープンソースであり、私はもともとそれぞれのライブラリにソースをコンパイルしているので、ライブラリのソースを編集することは問題ではありません。私はちょうどこのような状況で他の人が何をするかを見ようとしていました。 – Bee

関連する問題