どこかで以下のようなエラーを見かけたので、
それについて書いておこうと思います。
それについて書いておこうと思います。
■メッセージ例
error LNK2019: 未解決の外部シンボル “__declspec(dllimport) class std::basic_ostream > &
__cdecl std::operator<< >(
class std::basic_ostream > &,char const *)” (__imp_??$?6DU?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z)
が関数 “hogehoge(void)” で参照されました。
■原因
libを作った環境でのSTL実装と、exeを作ろうとした環境でのSTL実装が違うためにこの問題は起こります。
最近の例だとVisualStudio2005とVisualStudio2008の混在させて使うような状況で起こりえます。
この例でいえば、VCランタイムはDLL版を使っています。
かといってVCランタイムのスタティック版を使ったからといってこの問題は解決できません。
そのときには、”○○は未解決です”というリンクエラーが出ることになるでしょう。
■解決策
使用するlibとexeとでコンパイラのバージョンを一致させる。
もし、一方がビルド不能なのであれば、そちらにあわせることになるでしょう。
■感想
こういうことがあるからあまりSTLって使いたくないんですよね。
長い間使いたいようなlibを作る場合には、特に。
コメント
はじめまして。
私が学校のほうでVisualStudio2005を使い、自宅のほうでVisualStudio2008を使っているため、
これと同じような状況に陥っているのですが、使用するlibとexeとでコンパイラのバージョンを一致させる…とはどうすればいいのでしょうか?
大変恐縮だとは思いますが、出来るだけ詳しくご教授願えたら
幸いです。
> 通りすがりの学生 さん
その環境についてもう少し詳しいことを教えてください。
それぞれの環境(学校/自宅)ではどのような構成でプログラムを作成されているのでしょうか?
予想ですが、
学校で、"●●.lib"を使ってプログラムを作成しなさいというお題があり、そのlibは配布された物である。
そのlibを持って帰り、そのお題をクリアするプログラムを作成する、
というような感じでしょうか?
(そして当然ながら配布されたlibにはソースコードは付属しない、と)
構成というと、○○.hということでしょうか。
学校の方では特にlibを意識してソリューションを作ってはいないので、分かりません。
この記事で仰っているとおり、構成が違うのでこのようなバグが起きているとは思うのですが、なにぶん環境や構成の確認方法が分からなくて…
大変お手数なのですが、構成の確認方法を教えてくれれば幸いです。
なお、友人にも問い合わせたところ、友人のほうでも同じバグが発生しているようです。
補足になりますが、今回のエラーは学校で作成したプログラムを自宅のほうで少し改造してみようと実行したところ、エラーが発生しました。
学校の方ではエラーは発生しません。
また、教科書の簡単な例題を打ち込んでみたのですが、それもエラーが発生します。参考になるかは分かりませんが、以下に教科書の例題を書きこんでおきます。
#include <iostream>
using namespace std;
int main()
{
int a;
cout << "a";
cin >> a;
a++;
cout << "a = " << a << endl;
return 0;
}
なるほど、情報ありがとうございます。
このサンプルのプログラムですが、
これを自宅のVisualStudio2008(以後vs2008)の環境で、
新規にWin32コンソールアプリケーションとして作成した場合には
今回のような問題が起こるかどうか確認してみてください
(おそらく発生しないだろうと考えています)
一方で、同じようなエラーが発生した、と説明されているのですが、
公開するにあたって問題となる部分(関数名とか)を適当な関数名に変更して、ここに貼り付けてもらうことは可能でしょうか?
● 構成について
今回作成されているプログラムでは、
あなたが編集することの出来るプログラムコード(h/cpp)の他に、
外部のライブラリを用いていたりするかどうかが気になりました。
たとえば、VS2008上でプロジェクト開き、
ソリューションエクスプローラーで対象プロジェクトを右クリックしてプロパティを開きます。
そこで、リンカ→入力 と辿って、"追加の依存ファイル"という項目に
どのような記載があるかを確認してみてください。
また、#pragma comment(lib, "xxxx" ) のような記載が
ヘッダファイルor cppソースコードでかかれていないかチェックしてみてください。
(xxxxは何らかのライブラリ名がはいります)
win32コンソールアプリケーション→コンソールアプリケーションにチェック、空のプロジェクトのチェックを入れる、プリコンパイル済みヘッダのチェックを外す→完了でソリューションを作成し、4のプログラムを打ち込んでみましたがエラーが発生しました。
友人のほうには、短いのでコメント4に書いてあるプログラムを打ち込んでもらいました。しかし、やはりエラーが出るようです。
また、"追加の依存プログラム"には特に何の記述もありませんでした。
(継承の値という欄には、kernel32.libやuser32.libが記述してありました)
たびたび申し訳ありません。
念のため、エラーの内容を書き加えておきます。
1>a.obj : error LNK2019: 未解決の外部シンボル "__declspec(dllimport) class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl std::operator<<<char,struct std::char_traits<char> >(class std::basic_ostream<char,struct std::char_traits<char> > &,char const *)" (__imp_??$?6DU?$char_traits@D@std@@@std@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@0@AAV10@PBD@Z) が関数 _main で参照されました。
1>C:Users●●●Desktopべんきょ45Debug45.exe : fatal error LNK1120: 外部参照 1 が未解決です。
なるほど、私が知っている内容とはちょっと異なるようです。
この記事の内容は、通りすがりの学生さんの問題解決には役に立たなさそうです。
確認させてほしいことがさらにいくつか出てきました。
・OS環境はなんでしょうか?(Win7,XP, およびPro/Homeなどのエディションも)
・VS2008ですが、エディションは何でしょうか?またServicePack適用有無を教えてください(不明時は不明で結構です
・WindowsSDKなるものを別途インストールしてしまったりしていますか?
WindowsSDKを別途入れたりしてしまっているのではないか?
VC2008Expressだったりするのではないか?
と心配しているところです。
OSは自宅がVista、学校の方がXPです。ProかHomeかは思い出せません。おそらくProだとは思いますが・・・
VSはExpressEdtionでした。ServicePackについては、SP1というのがCドライブにあったため恐らく適用されていると思われます。
SDKというのは
Microsoft DirectX SDK (February 2007)と
Microsoft Platform SDK for Windows Server 2003 R2の二種類がCドライブに存在しました。
最初にエラー内容を書き加えればいいのに、遅くなったせいでここまでのお手数をおかけし大変申し訳ありませんでした。夜分遅くまでお答え頂き、大変恐縮でした・・・
手元でも同様の環境(Vista + VisualC++2008ExpressEdition)を用意してみました。
そこで同じプログラムでも症状が発生しないことを確認できてしまいました。
Visual C++ 2008 Express Edition を起動します。
"ヘルプ"-"VisualC ++2008 Express Editionのバージョン情報"を開いて見てください。
開いたウィンドウに情報が出ていると思うのですが、
Microsoft VisualStudio 2008
Version 9.0.30729.1 SP
と、このような記載になっているでしょうか?
情報のコピーというボタンを押して、情報をコピーしました。念のため、こちらで最新版のサービスパックをDLしようと思います。
以下が内容です。
Microsoft Visual Studio 2008
Version 9.0.30729.1 SP
Microsoft .NET Framework
Version 3.5 SP1
インストールされている Edition: VC Express
Microsoft Visual C++ 2008 91909-152-0000052-60326
Microsoft Visual C++ 2008
Microsoft Visual C++ 2008 Express Edition SP1 – 日本語 用の修正プログラム (KB945282) KB945282
この 修正プログラム は Microsoft Visual C++ 2008 Express Edition SP1 – 日本語 用です。
後で最新版の Service Pack をインストールした場合、この修正プログラムは自動的にアンインストールされます。
詳細については、http://support.microsoft.com/kb/945282 を参照してください。
Microsoft Visual C++ 2008 Express Edition SP1 – 日本語 用の修正プログラム (KB946040) KB946040
この 修正プログラム は Microsoft Visual C++ 2008 Express Edition SP1 – 日本語 用です。
後で最新版の Service Pack をインストールした場合、この修正プログラムは自動的にアンインストールされます。
詳細については、http://support.microsoft.com/kb/946040 を参照してください。
Microsoft Visual C++ 2008 Express Edition SP1 – 日本語 用の修正プログラム (KB946308) KB946308
この 修正プログラム は Microsoft Visual C++ 2008 Express Edition SP1 – 日本語 用です。
後で最新版の Service Pack をインストールした場合、この修正プログラムは自動的にアンインストールされます。
詳細については、http://support.microsoft.com/kb/946308 を参照してください。
Microsoft Visual C++ 2008 Express Edition SP1 – 日本語 用の修正プログラム (KB947540) KB947540
この 修正プログラム は Microsoft Visual C++ 2008 Express Edition SP1 – 日本語 用です。
後で最新版の Service Pack をインストールした場合、この修正プログラムは自動的にアンインストールされます。
詳細については、http://support.microsoft.com/kb/947540 を参照してください。
Microsoft Visual C++ 2008 Express Edition SP1 – 日本語 用の修正プログラム (KB947789) KB947789
この 修正プログラム は Microsoft Visual C++ 2008 Express Edition SP1 – 日本語 用です。
後で最新版の Service Pack をインストールした場合、この修正プログラムは自動的にアンインストールされます。
詳細については、http://support.microsoft.com/kb/947789 を参照してください。
Microsoft Visual C++ 2008 Express Edition SP1 – 日本語 用の修正プログラム (KB948127) KB948127
この 修正プログラム は Microsoft Visual C++ 2008 Express Edition SP1 – 日本語 用です。
後で最新版の Service Pack をインストールした場合、この修正プログラムは自動的にアンインストールされます。
詳細については、http://support.microsoft.com/kb/948127 を参照してください。
うーん、正しいですね。
根本解決ではないのですが、
今とりあえず動かせるようにするという観点から以下の変更をやってみてもらえますか?
プロジェクトのプロパティで、
"C/C++"-"コード生成"-"ランタイムライブラリ" と辿って、
"マルチスレッドデバッグDLL(/MDd)"
↓
"マルチスレッドデバッグ(/MTd)"
に変更して、リビルドを行ってみてください。
教えてもらった通りにリビルドを実行したところ、以下のエラーが発生しました。
1>—— ビルド開始: プロジェクト: 45, 構成: Debug Win32 ——
1>リンクしています…
1>LIBCMTD.lib(stdexcpt.obj) : error LNK2005: "public: __thiscall std::bad_cast::bad_cast(char const *)" (??0bad_cast@std@@QAE@PBD@Z) は既に a.obj で定義されています。
1>LIBCMTD.lib(stdexcpt.obj) : error LNK2005: "public: __thiscall std::bad_cast::bad_cast(class std::bad_cast const &)" (??0bad_cast@std@@QAE@ABV01@@Z) は既に a.obj で定義されています。
1>LIBCMTD.lib(stdexcpt.obj) : error LNK2005: "public: virtual __thiscall std::bad_cast::~bad_cast(void)" (??1bad_cast@std@@UAE@XZ) は既に a.obj で定義されています。
1>a.obj : error LNK2019: 未解決の外部シンボル "public: bool __thiscall std::locale::_Iscloc(void)const " (?_Iscloc@locale@std@@QBE_NXZ) が関数 "class std::ctype<char> const & __cdecl std::use_facet<class std::ctype<char> >(class std::locale const &,class std::ctype<char> const *,bool)" (??$use_facet@V?$ctype@D@std@@@std@@YAABV?$ctype@D@0@ABVlocale@0@PBV10@_N@Z) で参照されました。
1>a.obj : error LNK2019: 未解決の外部シンボル "public: class std::locale::facet const * __thiscall std::locale::_Getfacet(unsigned int,bool)const " (?_Getfacet@locale@std@@QBEPBVfacet@12@I_N@Z) が関数 "class std::ctype<char> const & __cdecl std::use_facet<class std::ctype<char> >(class std::locale const &,class std::ctype<char> const *,bool)" (??$use_facet@V?$ctype@D@std@@@std@@YAABV?$ctype@D@0@ABVlocale@0@PBV10@_N@Z) で参照されました。
1>a.obj : error LNK2001: 外部シンボル ""private: static short const * const std::ctype<char>::_Cltab" (?_Cltab@?$ctype@D@std@@0PBFB)" は未解決です。
1>a.obj : error LNK2019: 未解決の外部シンボル "void __cdecl std::_Xlen(void)" (?_Xlen@std@@YAXXZ) が関数 "public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > & __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::append(unsigned int,char)" (?append@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@ID@Z) で参照されました。
1>a.obj : error LNK2019: 未解決の外部シンボル "void __cdecl std::_Xran(void)" (?_Xran@std@@YAXXZ) が関数 "public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > & __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::assign(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,unsigned int,unsigned int)" (?assign@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QAEAAV12@ABV12@II@Z) で参照されました。
1>a.obj : error LNK2019: 未解決の外部シンボル "public: __thiscall std::ios_base::Init::Init(void)" (??0Init@ios_base@std@@QAE@XZ) が関数 "void __cdecl std::`dynamic initializer for ‘_Ios_init”(void)" (??__E_Ios_init@std@@YAXXZ) で参照されました。
1>a.obj : error LNK2019: 未解決の外部シンボル "public: __thiscall std::ios_base::Init::~Init(void)" (??1Init@ios_base@std@@QAE@XZ) が関数 "void __cdecl std::`dynamic atexit destructor for ‘_Ios_init”(void)" (??__F_Ios_init@std@@YAXXZ) で参照されました。
1>C:Users●●●Desktopべんきょ45Debug45.exe : fatal error LNK1120: 外部参照 7 が未解決です。
1>ビルドログは "file://c:Users●●●Desktopべんきょ4545DebugBuildLog.htm" に保存されました。
1>45 – エラー 11、警告 0
========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ==========
このエラーを見ると、サンプルのコードは a.cpp として実装しているのでしょうか。
今までの挙動から考えるに、ライブラリファイルとヘッダの整合性がとれていない気がします。
しかも、VisualC++の設定レベルの話で。ちょっと厄介そうです。
VisualC++2008Expressのオプションから、
"プロジェクトおよびソリューション"-"VC++ディレクトリ"を開き、
"インクルードファイル"と"ライブラリファイル"で設定されている項目はどのような物になっているか教えてもらえますか?
心配しているのは、
「一方はVC標準、他方はPlatformSDKの方」という不整合が起こっているのでは?と考えています。
ところで、"Microsoft Platform SDK for Windows Server 2003 R2"はVisualC++2008ExpressEditionをインストールするときに、
一緒に手動で導入したのでしょうか?
VC2008Expressでは、2005のころと違いPlatformSDKを別途インストールしなくてよくなっています。
そうですね、ソースファイルという所にa.cppという形で入っています。
"インクルードファイル"と"ライブラリファイル"にPlatformSDKが手動で入っていたので、削除してみたらエラーが発生せず無事に実行出来ました!
私の質問に、その場で親切丁寧にお答えして頂き本当にありがとうございました!感無量です!
おぉ、それはよかったです。
結局、PlatformSDKが悪さをしていたんですね!
これで自宅でもC言語の勉強が出来ます。
しつこいようですが、本当にありがとうございました。