鏑矢の憂鬱2000年10月前半
透明1ドットイメージ
 
2000/10/01 (Sun)
・今日もお便り紹介〜。
 
透明1ドットイメージ
透明1ドットイメージ
 MFCと言うよりはVCの機能かもしれませんが、プログラム中の使用スタックを制限(表示)できる方法ってあるのでしょうか?って言うより教えて下さい。これ以上のスタックを使用したらワーニングが出るなどなど。。。
透明1ドットイメージ
透明1ドットイメージ
 
・これは /STACK オプションですね。メニューの【プロジェクト】−【設定】ダイアログの【リンク】−【アウトプット】ページの【スタック アロケーション】の部分でも設定できます。こういうのってリンカの設定なんだなー。確かに Exe 全体での設定だからそうなのかも。でも DLL と別々に設定したらどうなるんだろう……。
 
・でわまたっ!
透明1ドットイメージ
 
2000/10/02 (Mon)
・今日もお便り紹介〜。
 
透明1ドットイメージ
透明1ドットイメージ
 こんにちは。
 fscanf()の件ですが、fgets()+sscanf()ならfgetsの時点でバッファの最大領域を指定できますのでまずバッファオーバーフローをここでチェックできます。
 sscanfで文字列型を取得するにしてもfgetsで使ったバッファサイズと同じだけ領域を確保しておけば絶対バッファオーバフローは起こりませんから。
 そして一番重要なのはファイルポインタを操作しなくても同じ行を再評価できるという点です。
 例えばデータベース的なテキストファイルを使う場合など、その行のキーデータを検索してデータを処理するかどうか決めたりしますが、fscanf使っちゃうと毎回全データを変数に取得してから判断するか、キーデータだけ読み込んで処理の必要があった場合にseekで戻すかしないといけなくなりますが、fgetsで文字列にとっておけば簡単です。
 まあ私としてはこんな理由だけしか知らないのですが。
 
 では。
透明1ドットイメージ
透明1ドットイメージ
 
・どうもですー。やっぱそういうところへんが焦点になっちゃいますね。 fscanf() がいけないってゆー文を見ると「 scanf() と同じくエラーチェックができない」みたいなことが書かれてること多いです。だからちょっと違うみたいですね。でもこー見てると、エラーチェックよりもオーバーフローとかファイルアクセスのボトルネックとかの方が重要な気もする(爆)。まーあんま気にしなくていーか、とりあえず fgets() と sscanf() でいいっぽいし。
 
・おまけ。 gcc や BCC の最新コンパイラ(つまり Visual C++ 6.0 は除く(汗))なら、 NULL の代わりに次のようなクラスを使用することができます。
 
class CNuller
{
public:
    //    Effective C++ P.131 のもの。
    //    下のメンバ関数は VC6 では通りません。
    template< class type_Ret >
    operator type_Ret *()
    {
        return reinterpret_cast< type_Ret * >( 0 );
    }
};

CNuller null;

// 使用例。
void use_null()
{
    int *pi = null;
    printf( "%X\n", pi );    // 0

//	int i = null;	// エラー。
}
	
 
・整数値には変換できない、ポインタとしてのみ機能する 0 、それが null 変数。もし必要なら値を 0 以外にも変更できるし、 == とかの比較にも使えるし、なにより NULL とまったく同じように使える。問題は、知らない人が見たら混乱の元ってことだな(爆)。しかも使えるコンパイラえらい制限されるし。こーゆーのが広まる頃には C++ に組み込まれちゃいそうな気もするし。むー。
 
・でわまたっ!
透明1ドットイメージ
 
2000/10/03 (Tue)
・最近お便り多くてうれしいにょ〜。では今日のお便りっ!
 
透明1ドットイメージ
透明1ドットイメージ
 こんばんわ。八木田です。たびたびお世話になります。
 
 現在 VB で 「コントロールの Change イベントが発行されない」という謎のエラーに四苦八苦しています。で、この問題がらみで SetWindowText() API が怪しいんじゃないかと考えていて、質問があります。この API を MSDN で調査した結果、以下の結論に達しているのですがあっているでしょうか?
 
1. SetWindowText() をコールすると WM_SETTEXT メッセージが送信される。
2. このメッセージは SendMessage() で処理される。
 
 どうでしょうか? もしこの結論が正しければ、ますます VB のエラーに対処できなくなります(T_T)
透明1ドットイメージ
透明1ドットイメージ
 
・こんばんわー。どうやら MSDN を見る限りそういうことみたいです。 SetWindowText() から WM_SETTEXT が送られるのはほぼ確実。成功か失敗かを戻り値として返すってことから、たぶん SendMessage() で処理が終わるまで待ってるんでしょう。 VB は持ってないんで、そっちの対処方法はちょっと分からないです。ごめん。
 
・ふたつめのお便り〜。
 
透明1ドットイメージ
透明1ドットイメージ
 なぜfscanfを使わず、fgetsとsscanfを使え、というかというと、エラーチェックができるから、です。
 要は読み込んできた行がscanfで指定しているフォーマットに合致しているかどうかチェックしてからscanfで切り分けが出来る、と。
 fscanfだと読み込んできた行をチェックすることなく通しますので、データによってはスタック破壊とか、いろんなことが起こりえます。
#%sのところに想定より長い文字列をぶち込むだけでOkですし
 とりあえずfgetsでバッファに読み込み、簡単にチェックするだけでスタック破壊などを回避することができないわけではありません。
 とはいえ、そこまでやるんだったら自前で切り分けたほうがいいかもしれませんね(笑)
#実際、私はscanf系使ったことないです。
透明1ドットイメージ
透明1ドットイメージ
 
・それだ! そうそう、知りたかったのはその関係なんです。なるほど、 fgets() で取り込んだあと isdigit() とかでチェックしてから sscanf() することでエラー回避ができるってことなんですね。わてはずっと「 fscanf() と sscanf() は同じようにエラー返すんだから、 fscanf() の方が悪いってことないやん」とか思ってたんですが、実際には scanf() 系のエラーチェックを信用しないで自前で処理すべきなんですな。
 
・いやーこれでひと安心。ってゆーのも、この辺がはっきりしないと「 std::fstream の方が良いぞよ」とか言えないんで(爆)。 std::fstream は fgetc() でひとつずつ取り込んで値のチェックしてから値返すっていう実装になってるんでまったく問題なし。オーバーロードを使ってるからタイプセーフだし。しかし、ってことはぷらとわのはやや間違ってることに? うむ、ちょっと考えてみよう。とにかく情報ありがとう!!
 
・でわまたっ!
透明1ドットイメージ
 
2000/10/04 (Wed)
・今日はお便りなし〜。代わりと言ってはなんだけど、今日から STL & iostream 入門の再放送がスタートしました。「1週間経つまでに読まないと、っていうプレッシャーがある方がいい」っていう方は購読登録しましょう(爆)。マイペースなあなたには、9日公開予定のCodian版をご期待ください。 C++ やってる人なら少しは気になるでしょー、 STL や iostream って。うふふ。
 
・でわまたっ!
透明1ドットイメージ
 
2000/10/05 (Thu)
・ぐはぁ、 scanf() 系の問題をやっとこさ理解しました!!
 
void Test()
{
    char ch[] = "10000000000";
    int i = 0;
    int iRes
        = sscanf( ch, "%d", &i );
    TRACE( "ch: %d, iRes: %d\n", i, iRes );
//  ch: 1410065408, iRes: 1
}
	
 
・と、「型はあってるけどオーバーフローしてる」場合、 scanf() 系はエラー返さないうえに無理矢理読み込んじゃうんですね(汗)。こりゃやべーや。このチェックをするために、まず fgets() で取り込んで、オーバーフローチェックをして、 sscanf() する、って手順になるわけですな。ちなみにもちろん std::fstream はオーバーフローチェックもしてくれるんで大安全(爆)。ぷろとわ書き直さなくっちゃ。
 
・もとい。これは sscanf( ch, "%10d", &i ) って書けば解決しちゃうな。って、オーバーフローが解決するだけで値は変なまま(無理矢理切り捨て)だから問題の解決にはなってないですな。むしろこっちの方が問題かも。結局値のチェックは必要ってことやね。でも自前でチェックするコード書くの大変だなー。 iostream の方が100倍楽だもんなー。
 
・今日のお便り!
 
透明1ドットイメージ
透明1ドットイメージ
 UmiBoseです、こんにちは。
 結局、フレームウインドウに子供ウインドウを乗せて作りました。
 やっぱり、前だれかが質問された様にフレームウインドウのスタイルにWS_EX_CLIENTEDGEが付いていました。defaultでつくみたい?
 ・・・で、全体の再描画の方法は?って問題になりますね〜。(とりあえず、立ち上がりに最小化して元に戻してます)
透明1ドットイメージ
透明1ドットイメージ
 
・ウィンドウ全体の再描画……どうすればいいんだろう(汗)。 InvalidateRect() 系はクライアントエリアだけだし、 WM_NCPAINT 送ってもダメだった。うーむ、やっぱ送ってくれたサンプルコードどおり、最小化しちゃって戻すって方法が一番楽かも(爆)。ばれやしないし。あとウィンドウを1ドット縮小するようリサイズしてもいーかも。
 
    RECT stRect;
    pFrame->GetWindowRect( &stRect );
    pFrame->SetWindowPos( NULL, 0, 0, stRect.right - 1, stRect.bottom - 1
        , SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE );
	
 
・でもなんか……むぅ。
 
・でわまたっ!
透明1ドットイメージ
 
2000/10/06 (Fri)
・今日のお便り!!
 
透明1ドットイメージ
透明1ドットイメージ
 UmiBoseです、こんばんわ♪
 早速、質問っす。
 デバッグ終了時にでる↓ってどのように活用すればいいんでしょうか?
 
> Detected memory leaks!
> Dumping objects ->
> {161} normal block at 0x01102490, 136 bytes long.
>  Data: <       }(       > 94 01 07 01 15 0D 05 7D 28 00 00 00 18 00 00 00 
> {160} normal block at 0x01102550, 136 bytes long.
	
 
#メモリリークはわかったけど、そのあとどうしろと?
透明1ドットイメージ
透明1ドットイメージ
 
・こんばんわー。うむ、この辺の情報って少ないんですよねー。初心者向けの本とかでももっとやればいーのに。で、このエラーは VC のデバッグ版 new でメモリ確保して、 delete しなかった時に呼ばれます。メモリリークを検出する機能が、デバッグ版 new に付いてるわけです(注:正確には _Crtなんたら() なランタイムの機能ね)。
 
・このエラー、「 Dumping objects -> 」のあとに「 C:\Programing\Test\MainDlg.cpp(103) 」とか表示されると思うです。これが最重要。最後の (103) は行番号で、このファイルのこの行で new されたメモリが delete されてないんですよ、って教えてくれてるわけです。
 
・ {161} は new したものに付けられるインデックスナンバー、「 at 0x01102490 」は new が返したポインタ、「 136 bytes long 」は new が確保したサイズ、 <> の間に書かれてる文字列は確保したメモリ上を ASCII 文字に置き換えたもの、そのあとの「 94 01 07 01 」は置き換える前、つまりメモリ上をそのまま16進表示したもの(いわゆる「ダンプ」)。
 
・つまり! これらの情報を元に「どの new で確保したメモリが delete されてないか」を特定して、見つかったら任意のタイミングで delete するようにすればいい、というわけです。まー結局は最初のファイル名と行番号さえ分かればいいわけで、それ以外の(あまり役に立たない)情報がいっぱい付いてるんで分かりにいとゆーことですな。
 
・……そのファイル名が表示されない場合がある?(汗) そしたらきついかも。とりあえずメモリリークしてそうな new を探して、その new のあとに _CrtMemDumpAllObjectsSince() を呼ぶようにして、その new のインデックスナンバーをチェック、で、最後に出てくるメモリリーク情報のインデックスナンバーと照らし合わせて、どの new で作ったものが解放されてないのか調べる、って感じかなー。ちょっとめんどいね。
 
・でわまたっ!
透明1ドットイメージ
 
2000/10/07 (Sat)
・はにゃ〜ん、今日はお休みよん。久しぶりやねぇ。
透明1ドットイメージ
 
2000/10/08 (Sun)
・今日もお休み〜。そいや、最近、フリーウェアのバージョンアップをしたいなー感がちょっと高くなってます。とりあえずほんのちょっとでもいいから、バージョンアップしてみるかなー。
透明1ドットイメージ
 
2000/10/09 (Mon)
・ Codian で STL & iostream 入門を公開中! と宣伝したところで、今日のお便り。
 
透明1ドットイメージ
透明1ドットイメージ
 おはようございます。
 Aki です。
 template のことについて質問があります。まずは、プログラムを見てください。
 
#include <iostream.h>
#include <string.h>

template < class cType >
struct Object
{
	cType data;  // <-------- ( ア )
};

int main()
{
	Object< char[8] > a;  // <-------- ( イ )

	strcpy( a.data, "abcde" );
	cout << sizeof( a ) << ", " << a.data << endl;

	return ( 0 );
}
	
 
実行結果:
8, abcde
 
 上のプログラムで、( イ ) のように宣言した場合には、( ア ) の部分は、 char data[8]; と考えてさしつかえないのでしょうか?( たぶんこの考えは正しいとは思うのですが、確証がほしいです。 )
 毎度、くだらない質問で申し訳ありませんが、よろしくお願い致します。
透明1ドットイメージ
透明1ドットイメージ
 
・おお、こういう使い方があったのか(爆)。うんうん、こういうのオッケーです。 a.data = 100 とかしてみれば「error C2440: '=' : 'const int' から 'char [8]' に変換することはできません。」ってエラーが出るからちゃんと char[8] になってますね。この「無理矢理代入でコンパイルエラー起こして確認」は typedef とかの確認によく使います(汗)。
 
・テンプレートって、使い始めは「型の置き換えだよね」とか思うかもしんないけど、それは考えなくていいです(爆)。むしろ「 #define の代わり」、つまり単に置き換えるだけって考えた方がいいかも。指定したテンプレート引数に置き換えて、とにかく無理矢理コンパイルして、コンパイルできたらOK、って形式。だからこういう使い方もできるわけです。うん、こういう質問が一番好きだ(爆)。
 
・あっと、ひとつ補足。テンプレート引数には「整数値」も使えます。 template< int int_size > ってすれば int_size を定数値として使えるんで char[int_size] ってできます。もし char の配列ってことが確定してるんならこっちの方がいいかもしんないってことで。知ってたらごめん。
 
・でわまたっ!
透明1ドットイメージ
 
2000/10/10 (Tue)
・今日もお便り紹介〜。
 
透明1ドットイメージ
透明1ドットイメージ
 こんにちは。
 既に解決しているみたいですがfscanf()の代わりにfgets()とsscanf()を使う場合のことですが、整数のオーバーフローチェックはまず浮動小数型で読み込んでチェックした後に整数型で読み込むという方法も採れます。
 ですが、大体はユーザの作成したファイルから直接数値を読みとる事なんてほとんどなく、大抵はシステムファイルとしてパラメータを書き込んであるファイルやGUI等で設定した内容を保存するファイルから読み込むという場合がほとんどでこのような場合は読み込み自にエラーチャックなどしませんね。(前者は作るときにエラーが起きないようにするし後者はGUIでチェックするから)
 まあインターネット系のアプリなど危険なところでは厳密にチェックした方が良いのでしょうがね。
透明1ドットイメージ
透明1ドットイメージ
 
・情報どうもですー。そっか、浮動小数点として読み込んでから整数値にって方法もあるんだなー。あと、ファイルの中身のチェックはした方がいいと思うです(汗)。まーウィンドウズは拡張子があるからいいけど、うにくす系とかだとどんなファイル渡されるか分かんないし、拡張子が同じで中身が違う場合とかもあるかもしんないから。まーユーザーの使い方が悪いって言えばそれまでだけど(爆)。
 
・でわまたっ!
透明1ドットイメージ
 
2000/10/11 (Wed)
・うにゃー、辞書の方に CPU のこととかの難しいこと送らないで〜、と思いつつも、そういったことを調べるからこそ CPU の内部構造に詳しくなれる、って面もあるんで難しいところですにゃ。では今日のお便り!
 
透明1ドットイメージ
透明1ドットイメージ
 はじめまして。VisualC++6.0で質問があります。
 DLLで新規作成し、リソースでダイアログボックスを付けます。ここでDLGに「Activxコントロールの挿入」で「Microsoft FlexGridControl Version6.0」を追加します。その後がわかりません。予想では何の問題もなく実行できるはずなのですが(現にexeでは出来ました。)何故かDLGが表示されないのです。
 DLGプロパティは可視になっており、プロジェクトの設定も出来ていると思われます。もちろんソースも総チェック済み…。一体何が足りないのでしょう?そもそもなぜDLGが表示されないということが起こるのでしょうか?
透明1ドットイメージ
透明1ドットイメージ
 
・どうもはじめましてー。とりあえずひとつずつ確認していきましょう。まず、もう一度最初から DLL のプロジェクトを作って、まだ「Microsoft FlexGridControl Version6.0」を貼り付けない状態でビルドしてみて、ダイアログが表示されるか確認してみましょう。こうしてみないと、どこら辺に問題があるのか絞りきれないんで。
 
・もし表示されなかったら「Microsoft FlexGridControl Version6.0」とは関係ない問題ってことになります。そのときは「ダイアログのクラスも作ったか」「クラスはちゃんとエクスポートされているか」「 Exe から使っている DLL は最新のものか」といった部分をチェックしてみてください。
 
・ダイアログが表示されたら「Microsoft FlexGridControl Version6.0」の問題ってことになります。このコントロールのプロパティを色々変えるともしかしたらそういうことになるのかもしんない。ま、実はわては ActiveX にはあんまり詳しくないんでちょっと分かんないんだけど(汗)。中身の仕組みは分かるんだけど、 VB 使ったことないからその辺で知識不足……。
 
・でわまたっ!
透明1ドットイメージ
 
2000/10/12 (Thu)
・うわー、辞書が更新できないかもしれん。それは置いといて、今日のお便りはみっつ〜。
 
透明1ドットイメージ
透明1ドットイメージ
 こんばんわ!
 Aki です。
 
> そもそもなぜDLGが表示されないということが起こるのでしょうか?
 
 たぶん、ダイアログボックステンプレートが入っているモジュールの指定がおかしいのではないでしょうか?
 具体的には DllMain() に送られてくるインスタンスハンドルを使ってダイアログを作成しなければならないということです。
 Dll を呼び出すアプリケーションのインスタンスハンドルを使ってダイアログを作成しようとしても指定したダイアログボックステンプレートが見つからないので失敗してしまいます。
 ようするに、Dll 内のリソースにアクセスするには Dll のインスタンスハンドルが必要だと言う事です。
 
 まとはずれだったらごめんなさい。
透明1ドットイメージ
透明1ドットイメージ
 
・あ、それ考えてなかった(汗)。わては拡張 DLL で CDialog から派生して作ったんで、 MFC 使ってたからそーゆーことになんなかったんですね。非 MFC な DLL の時には DLL 側のリソースを読み込まなきゃいけないってこと忘れてました。情報ありがとうですー。ちなみに昨日の投稿者さんによると問題は解決したそうです。とりあえず良かった〜。
 
・次のお便り。
 
透明1ドットイメージ
透明1ドットイメージ
 メールの送信方法に付いて御質問します。
 VC++6.0,MAPIを使用してOutLock送信トレイに在るメールをプログラムにて送信したのです。
 Platform SDK: MAPIの"Sending or Receiving a Message on Demand"に従ってプログラムを作成しましたが、MAPI SpoolerのIMAPIStatusを求める為に"hr =IMAPISession::OpenEntry(---)"を実行した時、hr=0x80004005のエラーを返します。
 MAPI SpoolerのENTRY ID及びIIDは、正しくOpenEntry(---)に渡していると思います。
透明1ドットイメージ
透明1ドットイメージ
 
・あう〜ごめんなさい、わては通信関係全然分かんないんです(泣)。エラーも謎だしねぇ。 0x80004005 って IMAPISession::OpenEntry() のリファレンスに載ってるエラーコードの中にないし( MAPI だと MAPI_E_CALL_FAILED がこれに当たるみたいです)。誰か分かる人いたら教えて〜。
 
・最後のお便り。
 
透明1ドットイメージ
透明1ドットイメージ
 http://www.kab-studio.biz/Programing/Codian/index.htmlの文字配列への書き込みですが、std::strstreamはおかしいのではないでしょうか?
 標準C++において、従来のstrstreamに相当するのは、#include <sstream>で得られるstd::basic_stringstream<>を特殊化/typedefしたstd::stringstreamのはずです(プログラミング言語C++ 第3版 P503)。
 std::basic_string<>ベースのstd::stringstreamは、文字配列ベースのstrstreamに比べ、安全性/使い易さの点で上回っていると思います。
透明1ドットイメージ
透明1ドットイメージ
 
・ぎく!(汗) はい、実はこれ確信犯です。確かに std::strstream は std::stringstream に置き換わることになってます。 traits にも対応されてないから、ちょっと見捨てられてる状態ですね。でも std::stringstream だと、まず std::string について解説しなきゃいけない。それだと初心者には敷居が高すぎるんですよね。初めて iostream を使う人にとって、操作対象が標準入出力でもファイルでも std::string でもなく、文字配列だっていうことはとても安心感があると思うんです。
 
・まー C++ の性格上、 std::strstream がなくなるってことはないような気がする(汗)ってこともあるんで、とりあえずこのままでいこうと思ってます。でも確かに、 std::strstream しか知らないからこれを使ってくってことになったらそれは困るかも。Codian版で、最後に std::string と std::stringstream の解説を加えた方がいいかもしんない。
 
・でわまたっ!
透明1ドットイメージ
 
2000/10/13 (Fri)
・プログラミング辞書は問題なく更新できそうです。とりあえずひと安心。秀丸はやっぱすごい……。では今日のお便り!
 
透明1ドットイメージ
透明1ドットイメージ
 プログラミング辞書(http://www.kab-studio.biz/Programing/Dictionary/)でいくつか気になる説明があります。
 
explicit
 暗黙の型変換の危険性を説明しないと、このキーワードが導入された説明にならないと思います。
#プログラミング言語C++ 第3版 P.338, More Effective C++ P.27
 
TCHAR
 TCHARがマクロだとありますが、実際はtypedefです(VC++4.1/6.0で確認)。
 
void
 規格ではreturnでvoidを返すことが認められています。VC++でコンパイル出来ないのはMicrosoftの問題であって、C++とは無関係です。
#プログラミング言語C++ 第3版 P.191
 
volatile
 単一プロセス内の複数スレッドによって共有される変数に指定されることが多いと思います。
 
仮想関数
 クラス型変数のポインタだけでなく、参照を使った場合にも動的束縛が働きます。
透明1ドットイメージ
透明1ドットイメージ
 
・指摘ありがとうです! explicit 、気付かないうちにコンパイルが通っちゃってるのがまずいってこと書いてなかったです。なんか、引数ひとつの変換コンストラクタが諸悪の根元って気がしてきたなー。 TCHAR はこの前ぷらとわで「 typdef だ」って確認したのに(汗)。 return void 、とりあえず次のようなプログラムを作ってみました。
 
void RetVoid()
{
	return;
}

void Test()
{
	return RetVoid();
}
	
 
・うお、 gcc と bcb でコンパイル通った!!(喜) うわすごー、ちゃんとテンプレート用に C++ が変化してるんだなー。あと return void() も通ったけどちょっとこっちは不安(汗)。あとでプログラミング言語 C++ を見てみよう(実は持ってない(汗))。それにしてもこれはめっけもんだ。結局は VC.NET 待ちってことか〜。
 
・ volatile はよく分かんない(汗)。一応 Java ではマルチスレッドと関係あるみたいだけど、 C++ じゃあんま関係ないんじゃないかなー。仮想関数はミスでした、たぶんここ書くときに手抜きしたんだな(爆)。この辺は次の更新時に直しておきます。やっぱ結構穴があるなー。実際、こっち側ではまったくチェックできない分量なんで、気付いたところはどんどん指摘してくださいねー。
 
・でわまたっ!
透明1ドットイメージ
 
2000/10/14 (Sat)
・うにゃ、今日はお休みにゃの。
透明1ドットイメージ
 
2000/10/15 (Sun)
・今日もお休み。
 
 
(C)KAB-studio 2000 ALL RIGHTS RESERVED.