C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[8]: WinUnit でstringstreamは使えますか?


(過去ログ 104 を表示中)

[トピック内 9 記事 (1 - 9 表示)]  << 0 >>

■61817 / inTopicNo.1)  WinUnit でstringstreamは使えますか?
  
□投稿者/ poyonshot (1回)-(2011/09/07(Wed) 10:26:05)

分類:[C/C++] 

こんにちは、poyonshotです。

WinUnit のテストで、stringstream を使おうとするとリンクエラーが出るのですが、
ヘルプを見ても、何が足りないかわかりませんでした。理由がわかる方いませんか?


#include "stdafx.h"
#include <sstream>

using namespace std;

BEGIN_TEST(XXX)
{
stringstream strm;
}
END_TEST


エラーの内容
error LNK2001: 外部シンボル ""__declspec(dllimport) public: void __thiscall std::basic_streambuf<char,struct std::char_traits<char> >::setp(char *,char *)" (__imp_?setp@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QAEXPAD0@Z)" は未解決です。
error LNK2001: 外部シンボル ""__declspec(dllimport) public: char * __thiscall std::basic_streambuf<char,struct std::char_traits<char> >::epptr(void)const " (__imp_?epptr@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QBEPADXZ)" は未解決です。
error LNK2001: 外部シンボル ""__declspec(dllimport) public: void __thiscall std::basic_streambuf<char,struct std::char_traits<char> >::setg(char *,char *,char *)" (__imp_?setg@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QAEXPAD00@Z)" は未解決です。
error LNK2001: 外部シンボル ""__declspec(dllimport) public: char * __thiscall std::basic_streambuf<char,struct std::char_traits<char> >::egptr(void)const " (__imp_?egptr@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QBEPADXZ)" は未解決です。
error LNK2001: 外部シンボル ""__declspec(dllimport) public: char * __thiscall std::basic_streambuf<char,struct std::char_traits<char> >::pbase(void)const " (__imp_?pbase@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QBEPADXZ)" は未解決です。
error LNK2001: 外部シンボル ""__declspec(dllimport) public: char * __thiscall std::basic_streambuf<char,struct std::char_traits<char> >::eback(void)const " (__imp_?eback@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QBEPADXZ)" は未解決です。
fatal error LNK1120: 外部参照 21 が未解決です。

引用返信 編集キー/
■61822 / inTopicNo.2)  Re[1]: WinUnit でstringstreamは使えますか?
□投稿者/ とっちゃん (593回)-(2011/09/07(Wed) 11:56:32)
とっちゃん さんの Web サイト
No61817 (poyonshot さん) に返信
> エラーの内容
> error LNK2001: 外部シンボル ""__declspec(dllimport) public: char * __thiscall std::basic_streambuf<char,struct std::char_traits<char> >::eback(void)const " (__imp_?eback@?$basic_streambuf@DU?$char_traits@D@std@@@std@@QBEPADXZ)" は未解決です。
> fatal error LNK1120: 外部参照 21 が未解決です。
>
外部シンボルが未解決というエラー(LNK2001)は、そのプログラムソースやリンクするライブラリに含まれていないコードを呼び出そうとしたときに出るエラーです。

具体的には、CRTのリンクが指定されていない場合にでます。
エラー内容的には、msvcrt.lib(デバッグ版の場合は、msvcrtd.lib)を指定していないために発生していると思います。

おそらく、プロジェクトの設定の問題だと思いますよ。

引用返信 編集キー/
■61831 / inTopicNo.3)  Re[2]: WinUnit でstringstreamは使えますか?
□投稿者/ poyonshot (4回)-(2011/09/07(Wed) 14:45:59)
stdafx.h に下記を追加してリビルドしてみましたが、変わりませんでした。

#ifdef _DEBUG
#pragma comment(lib, "msvcrtd.lib")
#else
#pragma comment(lib, "msvcrt.lib")
#endif



ランタイムライブラリは マルチスレッド DLL /MD なのであっていると思うのですが。。。
引用返信 編集キー/
■61833 / inTopicNo.4)  Re[3]: WinUnit でstringstreamは使えますか?
□投稿者/ とっちゃん (594回)-(2011/09/07(Wed) 14:51:40)
とっちゃん さんの Web サイト
No61831 (poyonshot さん) に返信
> stdafx.h に下記を追加してリビルドしてみましたが、変わりませんでした。
>
> #ifdef _DEBUG
> #pragma comment(lib, "msvcrtd.lib")
> #else
> #pragma comment(lib, "msvcrt.lib")
> #endif
>
>
>
> ランタイムライブラリは マルチスレッド DLL /MD なのであっていると思うのですが。。。

状況が変わらないとすると、もう一つの msvcprt.lib(msvcprtd.lib)かもしれません。
が、pragma を追加したら解決するという可能性はかなり低い気がします。

もっと別の何かだと思います。それがなにか?はわかりませんが。

一度、プロジェクトの種類や設定(VSのバージョンやエディションもわからんですしね)を書いてみると何か見えてくるかもしれません。


引用返信 編集キー/
■61837 / inTopicNo.5)  Re[4]: WinUnit でstringstreamは使えますか?
□投稿者/ poyonshot (5回)-(2011/09/07(Wed) 15:48:34)
stdafx.h の #pragma once の次の行に、テストしやすいように下記の定義を追加していたのですが、これが原因だったみたいです。

#define private public
#define protected public

上記の行を stdafx.h の最後(最初から記述されている内容の後)に移動したら、リンクエラーがなくなりました。

これでなぜリンクエラーになるのかはわかりませんが、一応解決です。
解決済み
引用返信 編集キー/
■61839 / inTopicNo.6)  Re[5]: WinUnit でstringstreamは使えますか?
□投稿者/ とっちゃん (595回)-(2011/09/07(Wed) 16:03:46)
とっちゃん さんの Web サイト
No61837 (poyonshot さん) に返信
> stdafx.h の #pragma once の次の行に、テストしやすいように下記の定義を追加していたのですが、これが原因だったみたいです。
>
> #define private public
> #define protected public
>
> 上記の行を stdafx.h の最後(最初から記述されている内容の後)に移動したら、リンクエラーがなくなりました。
>
それならリンクエラーが出るのも納得。

> これでなぜリンクエラーになるのかはわかりませんが、一応解決です。
#define protected public
については最初のままでもエラーにはならないはずです。
実験してみてください。

でも、private のほうをもとの位置に戻すとエラーになるはずです。
これについては明確な理由があります。

解決済みになっているので、これ以上詳しくは書きませんが、きちんと学習しておくことをお勧めします。



解決済み
引用返信 編集キー/
■61840 / inTopicNo.7)  Re[6]: WinUnit でstringstreamは使えますか?
□投稿者/ poyonshot (6回)-(2011/09/07(Wed) 16:14:20)
とっちゃんさん、回答ありがとうございます。

> 解決済みになっているので、これ以上詳しくは書きませんが、きちんと学習しておくことをお勧めします。
よかったら教えていただけませんか?

private は、クラスのアクセス制限と継承のときに使うと思うのですが
public に変わっても問題ないと考えてるのですが、違うのでしょうか?


public -> private がまずいのは直感でわかります。

#define private public
#define protected public
自体がよろしくないのもわかっています。


引用返信 編集キー/
■61843 / inTopicNo.8)  Re[7]: WinUnit でstringstreamは使えますか?
□投稿者/ とっちゃん (596回)-(2011/09/07(Wed) 17:55:11)
とっちゃん さんの Web サイト
No61840 (poyonshot さん) に返信

> private は、クラスのアクセス制限と継承のときに使うと思うのですが
> public に変わっても問題ないと考えてるのですが、違うのでしょうか?
>
問題ないどころか問題の本質そのものです。
なにせ、今回LNK2001が発生した理由の本質がprivate から public に変更したように
見せかけたからなので。

今回のエラーは
1.privateな存在を public であるように見せかけた
2.C++標準ライブラリをDLLでリンクしようとした
3.VCのDLLは必要なものだけエクスポートされている
の3つが重なっているために発生しています。

試してないので本当かどうかはわかりませんが、スタティックリンクにしたら
リンクエラーは出ないのではないか?と考えます。
理由は3の部分が該当するわけですが...

ですが、本質部分は1にあり、この部分が理解できていないと結局のところ
3でエクスポートされているものが何か?がわからないため、エラーを解決できた理由が
わからないままであるということに変わりはありません。

class Base
{
private:
 int val;
};
void main()
{
 Base b;
 b.val = 0;
}

このプログラムがエラーになる理由はわかりますか?
それはなぜですか?ごく簡単に自分の言葉で説明してみてください。
それが説明できたら、

public にしたら何が変わらなければいけないかも説明してみてください。
private -> public に変えることで変わるものが何かを説明できれば
今回リンクエラーが発生した理由も見えてくると思いますよ。

引用返信 編集キー/
■61858 / inTopicNo.9)  Re[8]: WinUnit でstringstreamは使えますか?
□投稿者/ poyonshot (7回)-(2011/09/08(Thu) 22:48:47)
3.VCのDLLは必要なものだけエクスポートされている
について、考慮していなかったので、問題が発生したのですね。
MSDNによると
http://msdn.microsoft.com/ja-jp/library/a90k134d(v=vs.80).aspx

クラス内のすべてのパブリック データ メンバおよびメンバ関数をエクスポートするには、
__declspec(dllexport) キーワードは、以下のようにクラス名の左に記述します。

class __declspec(dllexport) CExampleExport : public CObject
{ ... class definition ... };

とあるので、クラスのメンバをpublicに変更したヘッダを使うことでエクスポートした
ものと矛盾が生じたと。


とっちゃんさん、おかげでひとつ賢くなりました。
ありがとうございました。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -