0

私はユニティビルドが初めてです。私はいくつかの調査を行ってきましたが、以下から素晴らしい情報を得ました。

しかし、いくつかのプロジェクトに変更を加え始めた今、私は少し混乱しています。

簡単にするために、ソリューションに 2 つのプロジェクトしかないとしましょう。ライブラリ プロジェクト (.lib ファイルを作成します) と実行可能プロジェクト。それらを LibProj と ExecProj と呼びましょう。

各プロジェクトは次のようになります。

LibProj
>include
>>Client.hpp<br>
>>Driver.hpp<br>
>>Verbose.hpp

>source
>>Client.cpp<br>
>>Verbose.cpp

ExecProj
>source
>>MyMainFile.cpp<br>
  Verbose.cpp

Verbose.cppデバッグ目的で使用されます。ostream をラップするので、 を使用する代わりに をcout <<使用しますverbose <<。これは、詳細な出力をコンソールに表示するタイミングを制御するために行われます。私のリリース バリアントでは、詳細な出力はすべてスキップされます。

両方のプロジェクトに のコピーがある理由はVerbose.cpp、デバッグで LibProj をビルドしなくても ExecProj で詳細な出力を取得できるようにするためです。

Driver.hppClient.cpp使用しますverbose <<MyMainFile.cpp両方で関数を呼び出します。

言うまでもなく、通常のビルド方法ですべてが機能します。

今問題...

私はUnity.cppLibProj内に作成しました。その内容は次のとおりです。

#include "Client.cpp"
#include "Verbose.cpp"

LibProj は正常にビルドされます。ただし、ExecProj をビルドすると、リンク中に壊れます。

LibProj.lib(Unity.obj) : error LNK2005: "public: void __thiscall VerboseMonitor::print(char const *,int)"
(?print@VerboseMonitor@@QAEXPBDH@Z) already defined in Verbose.obj
LibProj.lib(Unity.obj) : error LNK2005: "public: __thiscall VerboseStream::VerboseStream(void)" 
(??0VerboseStream@@QAE@XZ) already defined in Verbose.obj
C:\Users\\...\ExecProj.exe : fatal error
LNK1169: one or more multiply defined symbols found

したがって、基本的には、lib ファイルに既に存在する冗長関数を再定義しているため、問題が発生します。

私の質問は、ファイルを個別にコンパイルすると機能するのに、unity ビルドでは機能しないのはなぜですか?

1 つの .lib ファイルと他の .lib ファイルの違いは何ですか? つまり、技術的LibProj.libにはVerboseMonitor::print両方のビルドケースでシンボルがあり、それらのシンボルは ExecProj によって再定義されます。ただし、ユニティ ビルド ケースは失敗します。

この問題を回避する 1 つの方法は、Verbose.cpp のみを含む別の lib ファイルを作成し、両方のプロジェクトから削除することです。ただし、なぜこれが最初に起こっているのかを理解したいと思います。

また、誰かがこの問題を回避するためのより良い方法を考えることができますか?

4

1 に答える 1

0

私は何が起こっているのか知っていると思います。

Unity.cpp には Verbose.cpp と Client.cpp が含まれています
-Verbose.cpp にはprintの実装があります。
-Client.cpp には、printの実装をもたらす Verbose.hpp が含まれています。
したがって、Unity.obj にはprintの 2 つの実装があります。

これは、ライブラリ (LibProj.lib) に、印刷の重複を含む .obj ファイルが1 つ含まれていることを意味します。そのため、ライブラリにリンクしようとすると、コンパイラはどのプリントを使用すればよいかわかりません。

これが通常のビルドで機能する理由は、通常、Verbose.cpp が印刷の実装を含む Verbose.obj を作成し、Client.cpp が印刷実装を含む Client.obj を作成するためです。これは、ライブラリ (LibProj.lib) に2 つの.obj ファイルが含まれており、それぞれにprintが定義されているため、コンパイラが 1 つを選択することを意味します (方法はわかりません)。

この理論をテストするために、2 つの Unity ファイルを作成しました。
Unity.cpp には Verbose.cpp が含まれます Unity2.cpp
には Client.cpp が含まれます

この実装により、私は構築することができます。これは、LibProj.lib に2 つの.obj ファイル (Unity.obj と Unity2.obj) があり、それぞれにprintの実装が含まれているため、シンボルの衝突がないためです。

これは単なる推測であり、私は間違っている権利を留保します:)。ただし、間違っている場合は修正してください。

ありがとう。

于 2013-01-04T00:54:49.053 に答える