2

私は、Qt(gui lib)、VTK(graphics lib)、およびその名前を言及せず、代わりにLIB_Xと呼ぶ非常にあいまいな別のライブラリを使用するC++プロジェクトに取り組んでいます。プロジェクトでは、GUIコンポーネントにQtを使用し、ジオメトリのレンダリングにVTK(より正確には、QtをサポートするVTKによって提供されるQVTKWidget拡張機能)を使用します。LIB_Xを使用してジオメトリを収集および操作します。

問題は、LIB_Xが実際にVTKを使用していることが判明したことです(どこで、どのように、それはクローズドソースであるかはわかりません)。最初は問題はありませんでした。両方のライブラリをリンクしてコンパイルしても問題はありませんでしたが、ある時点で特定の(そして非常に必要な)LIB_X関数を呼び出してコンパイルすると、すでに定義されているVTK lib/objに関する何かがたくさん発生しました。 LIB_Xdllのエラーで。

例(これは/ FORCE:MULTIPLEを使用しているため、ここでは警告です。/FORCE:MULTIPLEなしでエラーが必要な場合はお知らせください。投稿します):

1>LIB_X.lib(LIB_X.dll) : warning LNK4006: "public: __thiscall std::vector<double,class std::allocator<double> >::~vector<double,class std::allocator<double> >(void)" (??1?$vector@NV?$allocator@N@std@@@std@@QAE@XZ) already defined in vtkCommon.lib(vtkInformationDoubleVectorKey.obj);

/ FORCE:MULTIPLEを使用してみましたが、最初は奇跡のようでしたが、コードにランダムなエラーが発生し、ほとんどの場合ヒープエラーが発生します。メインプロジェクトからLIB_Xへのすべての参照を削除し、すべてのLIB_Xのものを処理する静的libを作成することにしました。私はC++の専門家ではないので、コンパイル済みのlibを使用しているときにlibの衝突をどのように処理するかはわかりませんが、静的libをメインプロジェクトにリンクするときにlibの衝突エラーが発生するので、それでも/ FORCE:MULTIPLEを使用する必要があります。

静的ライブラリを取得すると、ランダムエラーがなくなったように見え、静的ライブラリを介してメインプロジェクトのLIB_Xメソッドで多くのことを実行できましたが、どこからともなく、メインプロジェクトに新しいデータメンバーを追加しました。 class(s​​td :: vector of doubles)を実行すると、静的ライブラリのメソッドの1つで突然ヒープエラーが発生しました。新しいデータメンバーをコメントアウトすると、静的ライブラリのメソッドは正常に実行されます。正直なところ、それを調べる価値があるかどうかわからないので、現在のエラーを与えるのは嫌いですが、それが役立つ場合に備えて、とにかくここにあります:

注:約151行目でxutilityにクラッシュし、アサーションがポップアップ表示されます: "file:dbgheap.c line:1279 expression:_CrtIsValidHeapPointer(pUserData)"

エラーは、ベクトルベクトルdoubleをベクトルベクトルベクトルdoubleに追加した後に発生し、push_back行でクラッシュします。

std::vector<std::vector<double>> tmpVec;
for(srvl_iter = srvl.begin(); srvl_iter != srvl.end(); ++srvl_iter)
{
 tmpVec.push_back((*srvl_iter).getControlPoints());
}
this->_splines.push_back(tmpVec); //CRASH

ここでクラッシュし始めたのは、メインプロジェクトに新しいデータメンバーを追加したときだけです(静的ライブラリとは別に!)。新しいデータメンバーをコメントアウトすると、エラーがなくなります。

std::vector<std::vector<std::vector<double>>> _geometry; 

したがって、/ FORCE:MULTIPLEは悪いように見えますが、私には意味をなさないランダムエラーが発生します。他の解決策はありますか?私はねじ込まれていますか?LIB_XのVTKのリンクでできることはありますか?

4

2 に答える 2

1

LNK4006アプリをライブラリ(ライブラリLIB_Yと呼びます)にリンクするときに、多くのエラーが発生しstd::vector<std::string>ました。これは、アプリでも実行しました。少し実験した後、うまくいく1つの解決策を見つけました。LIB_Yを呼び出す別のDLL(たとえば、LIB_Y_WRAPPER)でLIB_Yをラップし、メインアプリをLIB_Y_WRAPPERにリンクします。

私の提案を試すには、次のことを行う必要があります。

  1. 「すべてのLIB_Xのものを処理する静的lib」を静的LIBプロジェクトからDLLプロジェクト(LIB_X_WRAPPERと呼びます)に変更します。
  2. LIB_X_WRAPPERのヘッダーファイルにLIB_Xヘッダーファイルが含まれていないことを確認してください。ラッパーは、LIB_Xヘッダーファイルで宣言されたデータ型(など)からアプリを完全に分離する必要があるため、これは非常に重要std::vector<double>です。LIB_X_WRAPPERのソースファイル内からのみLIB_Xのヘッダーファイルを参照してください。
  3. 静的ライブラリ内のすべてのクラスと関数の宣言を変更して、DLLからエクスポートされるようにします(DLLからのエクスポートの詳細が必要な場合は、この回答を参照してください)。

このソリューションは、LIBYで使用されるクラスのインスタンス化(コンパイラーで生成された関数)をアプリでstd::vector<std::string>のインスタンス化とは完全に分離していたため、私にとってはうまくいきました。std::vector<std::string>

余談ですが、クラッシュの原因は(のデストラクタにあるとコメントしていstd::vector<double>ます)、アプリでのインスタンス化が std::vector<double>LIB_Xでのインスタンス化とは異なるためだと思います。

于 2010-01-10T13:56:26.223 に答える
0

コメントアウトはおそらくランダムな運です-ヒープを破損している場合、すぐに表示されるとは限りませんが、stlベクトルは左右に割り当てと割り当て解除を行うため、エラーが検出されるのも不思議ではありません。

一部のライブラリでは、特定の順序で物事を含める必要があります。なぜ私にはあきらめてライブラリを適切に設計できないと言っているように見えるのかわかりませんが、それは悲しい事実です。ただし、vtkを含める場所にこのlib_xを含めない限り、問題はありません。

しかし、彼らはいくつかのリソースをめぐって争っている、または彼らが一緒に働くことを不可能にする不適切な何かを使用している可能性があります。それらを分離することでコンパイルを正常に機能させることができ、それでも失敗する場合は、このlib_xが設計された方法で失敗しているだけであり、非常にあいまいである可能性が低いため、運が悪いだけです。すべての用途に対して徹底的にデバッグされています。何かが広く使用されていない場合、それは通常、開発者のマシンとプロジェクトで機能するものになりますが、必ずしも他の人のものである必要はありません。

于 2010-01-09T21:19:48.027 に答える