#pragma twice

KAB-studio > プログラミング > #pragma twice > 083 Version 5.18 すべての道は API に通ず!

#pragma twice 083 Version 5.18 すべての道は API に通ず!

前のページへ 表紙・目次へ 次のページへ

 Version 5.18
すべての道は API に通ず!

というわけで、 std::ifstream::open() の中を見ていったら

    if (valid[n] == 0 || (fp = fopen(name, mods[n])) == 0)

というコードが出てきました
この fopen() って、ランタイムの fopen() ??
そう、つまり iostream はランタイムを利用してファイル入出力をしてる
んです!
へーっ、ま、 iostream は標準 C++ ライブラリ、ランタイムは標準 C ラ
イブラリ、使っててもおかしくないけど……でもそういう古いの使ってるっ
ていうのはやっぱ不思議かも
古い新しいっていうより、ローレベルハイレベルってことかも
前回の話ね。ファイル使うのはローレベル、クラス使って便利にしてるの
がハイレベル
 iostream はハイレベルの部分として使いやすくしてる、で、ローレベル
の部分は昔ながらのランタイムに任せてるってことだね
そういうもんなんだ
さて! 今度はこの fopen() の中に入ってみましょう!
ええっ、入れるの?
 Visual C++ にはランタイムのソースファイルが付いてるからね
……ソースファイル……
宣言が入ってるのがヘッダーファイル、定義が入ってるのがソースファイ

あー、 .h と .cpp ね
ランタイムのソースファイルには定義部、つまり関数の本体が入ってるか
ら、それを見て fopen() がどうなってるか見てみましょう
難しくない?
難しい部分は無視しましょう
うっ適当……
えっと、今の std::ifstream::open() の中の fopen() から入ってもいい
し、 fopen() 実際に呼び出すコード書いてそっから入ってもいいけど
 std::ifstream::open() からいこっとブレークポイント設置!
んじゃ入って
【中カッコに入る】ボタンでステップイン! _tfopen() って関数に入っ

これが fopen() の中身だね。【中カッコに入る】ボタンを2回押して
 _tfsopen() に入った
下の方に

    retval = _openfile(file,mode,shflag,stream);

って行があるからこの _openfile() に入って
【中カッコを飛び越える】ボタンを……
あーっと、それでもいいけど、この行をクリックしてから【カーソル行の
前まで実行】ボタン押してもいいかな
それどのボタン?
【中カッコの左上に右向き矢印】のボタン
ぽちっと。あっ一発で!
他にもブレークポイントを設置して実行ボタンとかね
よーするにいろんな方法でできるようにってことね
そゆこと
んじゃ _openfile() の中へゴー!
下の方に

    if ((filedes = _tsopen(filename, modeflag, shflag, CMASK)) < 0)

があるから
 _tsopen() の中に入ればいいんだよね、クリックして【カー(略)実行】
で……っとなんか変なダイアログ出た!
【あいまいさの解決】ダイアログだね。似たような関数がふたつあって、
Visual C++ がどっちか判らないときにこのダイアログが出ます
あたしもわかんない〜
こういうときは、頭に w が付いてない方を選んで
じゃー _openfile() っての。ん、どうなったのかな?
 _tsopen() のある行まで来たから
あ、そっか、じゃーステップイン!
この _tsopen() の下の方に……

    if ( (osfh = CreateFile( (LPTSTR)path,

って行があるでしょ
うん、んじゃこの行まで飛んでステップ
ちょいまちっ!
な、なに? CreateFile() の中に入るんじゃ…… CreateFile() ?
どっかで聞いたこと
ああっ!! これって…… API の CreateFile() なの?
そゆこと。やっとたどり着いたね
ど、どーゆーこと?
つまり、 fopen() でファイルを開くってことは、間接的に CreateFile()
を呼んでファイルを開くってこと
……つまりランタイム使ってると思ったら、ホントは API 使ってたと
そういうこと
ってことは iostream も API 使ってるってことで……あのーもしかして
うん、 MFC も API 使ってる
ええ〜!! なに、結局ファイル開くのって API 使ってるってことな
の!?
あ、もちろん開くだけじゃなくて、ファイル入出力は全部 API 使ってる
んです
なんか……ちょっと驚いたかも
驚く前に MFC の方も確認しておこうか。とりあえず【実行】ボタン押し

フツーに動くようにしてダイアログ閉じて、ね
そしたら

void CFileTestDlg::OnBtnShow() 
{
    CStdioFile cStdFile;
    cStdFile.Open( "Data.txt", CFile::modeRead );
    return;
// 以下取っておきましょう

いつものパターンね
テスト用だから開けたかどうかのチェックはナシ。じゃ、 
CStdioFile::Open() 呼んでる行にブレークポイントを設置して
ステップイン! CStdioFile::Open() に入った
6行くらい下に CFile::Open() を呼んでるところがあるから
これにステップイン! これって、いわゆる親クラスのメンバ関数に入っ
てるんだよね
そうそう、ファイル開いたりする機能は親クラスの CFile の方にあるから

 CFile::Open() の中に入って……ああっ!!

    HANDLE hFile = ::CreateFile(lpszFileName, dwAccess, dwShareMode,

というわけで、 MFC も API を使ってファイルを開いていましたとさ
めでたしめでたし、ってあのねー
簡単にまとめると

iostream  > fopen  > CreateFile
CStdioFile::Open() > CreateFile

って感じだね
最終的に API 呼んでるっていうのは、さっきのローレベルって話?
そういうことだね。まず基本的に、ファイル操作ってのは危険なことだっ
ていう認識が必要
そりゃそうよね、ウィンドウズの重要なファイルとか、間違えて書き換え
ちゃったりしたらまずいわけだし
だから、ファイル操作は API でしかできないようになってるわけ
 API 以外にはファイル操作する方法がないってこと?
さらにローレベルな機能使えばあるけど、基本的にはそういうこと。 API
だけが〈ファイル操作のための手段〉として提供されているわけ
そうやって問題が出ないようにしてるんだ
だから、ランタイムも iostream も MFC も、ファイル操作をするときに
は API を呼んでるわけ
ランタイムなんてなんか直接してそうだったのに
ランタイムだって人の作ったものだからね
どゆこと?
ライブラリの作られる順番は、 API が最初。まず API が作られます
うんうん
次にランタイムを作ります。ランタイムを作る人は〈ファイル操作をする
ときには API を使うんだ〉ってことを知って、 API を使うプログラムを組
むわけ
そっか、ランタイムだってそーゆーふーにプログラムとして作られるんだ
もんね
 iostream も MFC もそう。ライブラリって最初からあるし何気なく使え
るから〈なんかすごい〉とか思うかもしれないけど、所詮人の作ったもの
確かに
得体の知れないことしてそうでも、実際はそうでもないってことをちゃん
と分かっておいて
つまりライブラリの中身を見ようってこと?
それもひとつ。分からない部分も多いと思うけど、積極的に見ていって欲
しいかな。数少ない〈自分以外の人が作ったプログラム〉だしね
例にいいってことね。もうひとつは?
ランタイムとかは見られるけど、 API の中身は見られないから
あ、そういえばそうだよね。ソースファイル公開してないから?
 API の中身はすなわちウィンドウズの中身、だからね
あーそーいえばそーゆー訴訟してたね
で、 API の中身は見えないけど、見えなくったって、結局は得体の知れ
ないことしてるわけじゃないんだ、っていうことを憶えといて
 API の中身だって、誰かが作ったプログラムなんだ、ってこと?
そういうこと! まずは、どんなアプリもプログラムも、自分と同じプロ
グラマーが作ったんだっていう認識が大事
つまり、自分にだってそういうものは作れる!
そこまでは言えないけど、でもそういう考えは重要。とんでもない変なこ
としてるわけじゃなく、ちゃんとしたプログラムなんだっていうイメージが
重要だね
まとめ! 結局 API を呼んでファイル操作してる!
 API だけでできるようになってるってこと
ランタイムとかも、意味不明な操作じゃなくて、 API を使うっていう普
通のことをしてファイル操作してる!
だから、どんなプログラムも普通のプログラムなんだ、って思いましょう

/*
    Preview Next Story!
*/
そんな感じのこと、 LPCTSTR の時も言ってたよね
重要なことだから何度もってことで
だからどんどん長くなるんじゃない?
ぎくっ
というわけで次回
< Version 5.19 ファイル読み込みをブラッシュアップ! >
につづく!
ってゆーか Ver 5 っていつまで続くの?
もうすぐ半年になっちゃうね……
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。