#pragma twice

KAB-studio > プログラミング > #pragma twice > 324 Version 15.24 「プロジェクトの設定」リンク編(1)

#pragma twice 324 Version 15.24 「プロジェクトの設定」リンク編(1)

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

 Version 15.24
プロジェクトの設定リンク編(1)

【プロジェクトの設定】ダイアログ編、次は【リンク】ページね
このページでは、コンパイル後のオブジェクトファイルを結合して Exe 
や DLLを作る【リンク】の設定を行います
コンパイルの次ってわけね
まずは【一般】ページから。【出力ファイル名】は、そのまま Exe や 
DLL の出力先フォルダと出力ファイルの指定
ってことは、 Exe とかのファイル名ってここで好きに変えられるの?
そうだよ。たとえば、デバッグ用とリリース用とで出力先フォルダを変え
たり、さらにファイル名を変えたりできます
そか、プロジェクト単位、っていうか左上の【設定の対象】ごとに変えら
れるんだもんね
そういうこと。いろんな設定を試したい場合 Version 15.20 ( No.320 ) 
で説明した【構成】ダイアログを使っていくつも設定を作って、それぞれ
別のフォルダに出力したりファイル名を変えたりすればいいわけ
そうすればいろんな設定の Exe とかができるわけね
そういうこと。次の【オブジェクト/ライブラリ モジュール】は
はい! DLL 使う時に参照するライブラリファイルだね
 Version 15.07 ( No.307 ) から何度も使ってるね。ここで設定する以外
にも #pragma を使う方法とかもあるから
うん、それも教えてもらった
次の【デバッグ情報を生成する】は、これをオンにしないと
プログラムデータベース、つまり.pdbファイルが作られません
それって Version 15.19 ( No.319 ) で出てきた……げ、それがないと
デバッグできないんじゃん
そういうこと。だからデバッグ時には必ずオンにします
こういうのでオンオフできるんだ……
【デフォルト ライブラリをすべて無視】は、 Visual C++ と一緒に
インストールされたライブラリファイルを見るかどうか、っていう設定
んなの見なきゃだめじゃん
実際、これをオンにしてビルドするとリンクエラーになります
これ使うのってどういう時?
 Visual C++ 付属のライブラリを使用しない場合とかかな。全部自前で
作ったものを使う時には
これをオンにして、自分のライブラリファイルだけ見るわけね
次の【プロファイルを行う】は、これをオンにすると.mapファイルが作ら
れます
何そのファイル
このファイルについては【デバッグ】ページで説明します。問題は、実は
これ、オンにしても実際にはオンになりません
……どういうこと?
これをオンにして、たとえば上の【オブジェクト/ライブラリ モジュール】
の欄をクリックすると……
あれ?? 【インクリメンタル リンクを行う】になっちゃった
実はこれ、【プロファイルを行う】と【インクリメンタル リンクを行う】
が重なってるんです
重なってる!?
で、これは【インクリメンタル リンクを行う】の方が優先されちゃうか
ら、チェックをオンにしても【インクリメンタル リンクを行う】の方しか
オンになりません
ええー?
これは Visual C++6.0 のバグだね
パッチ当ててるのに直ってないし……
こういう場合は、下の【プロジェクト オプション】の欄で、
【プロファイルを行う】をチェックした時に指定されるオプション
【/profile】を書き込めばOK
あ、ここってもしかして【C/C++】ページと同じ?
そう。 Version 15.21 ( No.321 ) と同じように、このページでの設定は
下のこの【プロジェクト オプション】の文字列に置き換えられて、実際に
はリンカを実行する時のオプションとして指定されるんです
だから、上のチェックボックスが押せなくても、この欄で直接書いちゃえ
ばいいや、って話?
そういう話。どの欄がどのオプションか分かれば、その方が楽かもね
うーん……
で、最初は隠れている【インクリメンタル リンクを行う】は、その名の
通り【インクリメンタルリンク】を行います
なにそのリンク
たとえば、以下のプログラム

// Main.cpp
#include <Windows.h>

int WINAPI WinMain
    ( HINSTANCE p_hInstance
    , HINSTANCE p_hPrevInstance
    , LPSTR p_pchCmdLine
    , int p_iCmdShow
    )
{
    int i = 100;    // ここにブレークポイント。

    return 0;
}

ブレークポイントをセットして、ここで止めて
ほい止めた
その場で、 100 を 200 に変えて
へ? デバッグ中だよ!?
その、デバッグ中にプログラムの修正ができちゃうのが、
インクリメンタルリンク
そんなことできるんだ……
修正して保存したあと、ステップオーバーすると自動的にビルドされて、
そこからステップオーバーします。変数ウィンドウで見ると
ちゃんと i の中に 200 が入ってる!
デバッグ時にはオンがいいかな、便利だから
……でも、なんかちょっと不安かも
それはあるかも。確かに、うまくビルドできない時もあるから、一度止め
てから修正して、それからビルドした方がいいかな
やっぱね
最後の【MAP ファイルを生成する】も、【デバッグ】ページで
つかさっき言ってた .map ファイルってこれ?
そうこれ。これもデバッグのところでまとめて説明します
はーい
次は【アウトプット】ページ
う、ここは難しそう……
そうでもないよ。まず【ベース アドレス】だけど、これは 
Version 8.03( No.145 ) で一度教えてます
え? 嘘!
この値は【ベースアドレス】、つまりアプリケーションのメモリの【基準
となるアドレス】を決めます。っていうよりは、単にインスタンスハンドル
の値を決めるもの、ってところかな
そういえばそうだった。ここでインスタンスハンドルの値を決めて、それ
がメモリの基準点、みたいになるんだったね
普段これは変える必要ないかな。次の【エントリポイント シンボル】は
ん? 確かエントリーポイントって WinMain() のことだよね
そう。 WinMain() に限らず、プログラムの〈最初に呼ばれる関数〉が
エントリーポイントです。ここで指定するのは、そのエントリーポイントの
関数名
え? じゃあ WinMain 以外の名前にできるの?
そういうこと。試しに【WinMainZ】を指定してビルドしてみて
あ、リンクエラー

リンク中...
LINK : error LNK2001: 外部シンボル "_WinMainZ" は未解決です
Debug/BuildTest.exe : fatal error LNK1120: 外部参照 1 が未解決です。
link.exe の実行エラー

そこで、実際に関数名を【WinMainZ】にしてみましょう

// Main.cpp
#include <Windows.h>

int WINAPI WinMainZ
    ( HINSTANCE p_hInstance
    , HINSTANCE p_hPrevInstance
    , LPSTR p_pchCmdLine
    , int p_iCmdShow
    )
{
    return 0;
}

あ、通った!
まぁエントリーポイントの関数名を変える必要なんてないし、 MFC だと
もう決められてるからどうしようもないから
変える必要なしね
次の【スタック アロケーション】は、簡単に言うとローカル変数、つま
り関数内の変数を置いておくメモリのサイズ
関数内の変数、ってよーするにメンバ変数とかグローバル変数じゃない
変数ってことね
そういうこと。ちょっと試してみようか。まず、この中の【予約】の値を
【0x1000】にして
ほい
次にプログラムを以下のように修正して

// Main.cpp
#include <Windows.h>

int WINAPI WinMain
    ( HINSTANCE p_hInstance
    , HINSTANCE p_hPrevInstance
    , LPSTR p_pchCmdLine
    , int p_iCmdShow
    )
{
    char s[400000];

    return 0;
}

これをリビルド実行してみて
ほい。げ、エラーになった

例外処理 (初回) は BuildTest.exe にあります: 
    0xC00000FD: Stack Overflow。

これは、設定した【スタック アロケーション】、つまり〈ローカル変数
を置ける場所のサイズ〉よりも、ローカル変数の方が大きくなったから発生
したエラーです
ほー
デフォルトで 1MByte が設定されるから普段は設定を変える必要はないん
だけど、ものすごく変数のサイズが大きくなる場合には変えた方がいいか

そういう事ってあるの?
あんまりないかな。このエラーは、主に再帰呼び出しのプログラムミスで
発生することが多いかも
再帰呼び出しって Version 13.16 ( No.252 ) でやった、自分の関数を呼
び出すのだよね
そう。再帰呼び出しをして、それが無限ループすると変数が作られまくる
から
それで容量オーバーってわけね
それに、大きなデータって、たいがい最初はサイズが決まってないから、 
new とか malloc() 使って確保するから
え? これって別なの?
そう、こういう動的にメモリを取得するものはこの設定とは関係ないか

そっちで取得すれば問題ないわけね
話を戻して、今の【予約】欄の右にある【コミット】は、【予約】の分は
必要になったら確保するけど、【コミット】は最初から確保しておく分
最初からって、メモリそれだけ取ってたら無駄じゃない?
だからこれも普通は設定しないかな。というわけで次回に続く!
げ、こんな中途半端なところで!?

/*
    Preview Next Story!
*/
なにこの中途半端さ!
この章はちょっとバランス悪いかも……
ま、今に始まったことじゃないけどさー
う”
というわけで次回
< Version 15.25 プロジェクトの設定リンク編(2) >
につづく!
このシリーズもいつまで続くのやら
意外と早く終わるかも
しんじらんなーい
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。