- ベストアンサー
VC のビルド
VC2005で開発しています。 あるサンプルプログラムを.slnから呼び出すと正常に作動するのですが、ファイルを集めて自分でビルドするとリンクのところでシンボルエラーが出ます。 正常に作動する方は、mainプログラムを最後にコンパイルしていますが、作動しないほうはmainプログラムからコンパイルしています。 これが理由でリンクしないのでしょうか? そうであるならどうやってビルドする順番をコンパイラに指示すればよいのでしょうか。 どなたか解答お願いします。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
>質問は、プロジェクトをそのままビルドしたらうまくいくのですが >そのファイルを個別に集めてビルドするとうまくいかないということです。 つまり、 ・既存のプロジェクトファイルでビルド→成功 ・プロジェクトを新規作成して、上記とまったく同じファイルを追加してビルド→エラー と言う事ですね。 そして「どちらも、使われているソースファイルが完全に同じなのに、片方はビルド出来るし、片方はビルド出来ないので、悩んでいる」のですね。 だったら、原因は簡単。 たぶん、既存のプロジェクトは、プロジェクトファイルの中に「マクロの定義」が仕込んである筈。 だけど、質問者さんが新規作成した新規プロジェクトは「仕込まれてないといけないマクロが、プロジェクトファイルに定義されてない」筈だ。 なので、既存のプロジェクトと新規のプロジェクトでは、マクロ定義の有無に違いがあり、コンパイル結果も違ってしまう。 これが「プロジェクトを新規作成して、同一構成にしても、関数の重複のエラーが起きる原因」だと思う。 例えば、既存プロジェクトは、プロジェクトの構成に「マクロの定義」が足してあって「#define REREASE_VERSION」と書いてあるのと同一の効果があると仮定してみよう。 そして、ExcelMechanisms.cppに #ifndef REREASE_VERSION printMatrixInExcel(.....) //関数の実体 { (中身略) } #endif って書いてあって、同様に、TestBasicOptionPresentation.cppに printMatrixInExcel(.....) //関数の実体 { (中身略) } って書いてあったとしよう。 この状態で「既存プロジェクトをビルドする」と(ここから重要)「REREASE_VERSIONがプロジェクト構成で定義済みなので、ExcelMechanisms.cppにあるprintMatrixInExcel関数は無視されて、無かった事になる。一方、TestBasicOptionPresentation.cppにあるprintMatrixInExcel関数は無視されずにコンパイルされるので、関数の重複は起きない」ので、問題なくコンパイルされる。 同一のソースを新規プロジェクトに追加して、必要なマクロを定義しないままコンパイルしてしまうと(ここも重要)「REREASE_VERSIONがプロジェクト構成で定義されてないので、ExcelMechanisms.cppにあるprintMatrixInExcel関数は無視されてずにコンパイルされる。同様に、TestBasicOptionPresentation.cppにあるprintMatrixInExcel関数も無視されずにコンパイルされるので、関数の重複が起きてしまう」ので、コンパイル途中にリンカが「同じ関数が2つある!」とエラーになる。 と言う訳で「既存プロジェクトのプロジェクトファイルに、コッソリと何かのシンボルが定義されてるので、新規に作ったプロジェクトにも同じシンボル定義を入れる」と、コンパイルが成功する筈。
その他の回答 (4)
- php504
- ベストアンサー率42% (926/2160)
メニューの「プロジェクト」->「~のプロパティ」や「ビルド」->「構成マネージャ」を比べてみましょう
お礼
了解しました。 やってみます。
- redfox63
- ベストアンサー率71% (1325/1856)
> LNK2005: などのどのようなリンクエラーが発生しているのかをVC付属のMSDNなどで確認しましょう また、質問時に先のリンクエラーの識別文言などを明記すると回答の方向が期待しないものが集まることも少ないでしょう また処理の概要や同様のエラー(現象)になる最小手順(またはコード)を提示するのもひとつの方法ですよ 解決については chie65535氏の回答のように関数printMatrixInExcelの見直しが必要なように思います 寄せ集めて作成した際とslnで作成した際のファイル構成が違うのではありませんか または、ソースはソリューションに含まれているがコンパイルされていないとか slnの場合は#ifブロック内にprintMatrixInExcelが含まれていて片方がコンパイルされていないとか 思いつくのはこの辺ですが参考になれば幸いです
お礼
意見を総合すると、VCの設定を変えるというわけではなさそうですね。 まだ成功するほうのソースもあまり理解していないので、デバックモードでどんな動きしてるのか調べてみます。 皆様ありがとうございました。
- chie65536(@chie65535)
- ベストアンサー率44% (8740/19838)
>エラーの一部は >(略)printMatrixInExcel(...(略)...)は既に ExcelMechanisms.obj で定義されています。 >TestBasicOptionPresentation.obj エラーメッセージを良く読みなさい。 「名前と引数が完全に同一な、printMatrixInExcelと言う関数が、ExcelMechanisms.objとTestBasicOptionPresentation.objの両方にあるから、なんとかしなさい」って言ってる。 つまり「同じ関数が2つあるぞ」って言ってる。 2つある関数の中身が同一なら、片方を削除しなさい。 もし2つある関数の中身が違うのであれば「単純に片方を消す訳にいかない」ので、片方の関数名を変更し、呼び出してる部分も「どっちを呼ぶべきか、よく確かめてから、書き換えるか、そのままにしておく」か、問題が起きないように対処しなさい。
お礼
ご解答ありがとうございます。 質問は、プロジェクトをそのままビルドしたらうまくいくのですが、そのファイルを個別に集めてビルドするとうまくいかないということです。 関数名を変更とか、コードを書き換えるという作業は必要はないと思います。 でもすごく参考になります。 ありがとうございました。
- redfox63
- ベストアンサー率71% (1325/1856)
コンパイルする順序によってリンクエラーにはならないと思います その未定義シンボルはコンパイルしたファイル群の中で定義されているのですよね それとも自前のファイル群ではなくAPI関連の関数とかでしょうか CreateWindowとか BitBltとか strcmp/strcpyとか 後者であるなら 必要なライブラリファイル(.lib)をリンク時に参照していないのが原因でしょう その未定義シンボルのエラーメッセージの抜粋などを投稿してみましょう
お礼
お忙しい中、ご解答ありがとうございます。 私の場合、前者のパターンだと思います。 C++で計算した結果をエクセルで呼び出し、アウトプットしています。 エラーの一部は エラー 2 error LNK2005: "void __cdecl printMatrixInExcel(class NumericMatrix<double,long,class FullMatrix<double,class std::allocator<double> > > const &,class Vector<double,long,class FullArray<double,class std::allocator<double> > > const &,class Vector<double,long,class FullArray<double,class std::allocator<double> > > const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &)" (?printMatrixInExcel@@YAXABV?$NumericMatrix@NJV?$FullMatrix@NV?$allocator@N@std@@@@@@ABV?$Vector@NJV?$FullArray@NV?$allocator@N@std@@@@@@1ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) は既に ExcelMechanisms.obj で定義されています。 TestBasicOptionPresentation.obj といったものです。 いずれにしろ、うまく走っているものがある以上何かの参照し忘れとかそういった類だと思うんですけど。 未解決の外部シンボルでした。(汗)
お礼
あなたの想像力に脱帽です。 転職したくなったとき相談してください。 何とかします。