ちょっとした小さなツールをC++で組むとき、CRTは使わないときはできるだけCRTをリンクしないようにしたいわけです。
でも、エントリポイントに WinMainとかしてしまうと、コマンドライン引数をうまくハンドリングできなくて悩む。#define UNICODE とかして、UNICODEにすると、CommandLineToArgvWというAPIがあるので、簡単に、argc(int) と argv(char**)がとれてラクができますが・・・。
なぜか・・・ANSIバージョンの CommandLineToArgvA がないのはなんでなんでしょうかねぇ・・・。
というわけで、解決方法は3つ。
- そもそもANSI文字列を使わない。
- 自分でコマンドライン文字列(GetCommandLine API)パーサーを書く
- CommandLineToArgvWで得られた引数リストをANSI文字列に変換する
一番ラクそうなのは3かな・・・ということで、やっつけで書いてみましたが・・・これでいいのかな・・・(^^;;;
こんなんでエエのかな・・・。。。
CommandLineToArgvA() が無いのは、
__argc、__argv が定義されているからみたいです。
MinGW でコンパイル/実行してみましたが、うまく取得できました。
# その他の環境では未検証です。
参考ページ: http://eternalwindows.jp/winbase/window/window06.html
>たっちんさん
コメント、ありがとうございました。
ただ、__argc,__argvはCランタイムライブラリで内部的に定義されているグローバル変数だったかと思いますので、
VisualC++ 2008ExpressでCランタイムライブラリを使わずにWin32APIだけでコードを書くときには使えないんですよね。。。小さなツールだとWin32 APIだけで書いて、以下のようなコードをくっつけてビルドしてます。
C言語を使ってて、Cランタイムライブラリを使わない、ということ自体がイレギュラーですのでちょっと特殊用途なんですけどね(^^;
わざわざ検証コードも書いてくれてありがとうざいました。
参考ページのexternalwindows.jpは昔からよく参考にさせてもらってます(^^)
その後、いろいろ試してみた結果、
> __argc,__argvはCランタイムライブラリで内部的に定義されているグローバル変数
ということでした。
標準Cライブラリを抜いてリンクしてみると、
__argv のリンクエラーが発生しました。
また、-lmsvcrt オプションを手動で追加してみましたが、
実行時エラーが発生し失敗しました。
ヘッダファイルをやさがししたところ、
残念なことに stdlib.h にしっかり書いてありました。
ちなみに、Cライブラリを抜いてリンクすると、
実行ファイルサイズが 12KB→6KB になるという、
あまり役に立たない情報が得られました。
# MinGW ばかりで、スミマセン。。
# VC でも試そうかと思いましたが、体力がありませんでした。。
>たっちんさん
__argc,__argv は、main 関数がコールされる前に初期化されなければ使えないので、
Cランタイムライブラリを使わず、ユーザー定義のエントリポイントを使用する場合には使えませんね。
VisualC++でも、__argv,__argcは使えますが、確かマイクロソフトの公式ドキュメントには一切触れられていないと思うので使えないんですよね。以前はドキュメントにも載っていたんですが・・・なぜか消えた。
だからこそ、Win32 APIとしてなぜ CommandLineToArgvA がない理由がわからないんですよねぇ~(^^;;;
MinGWはCランタイムライブラリがあってもサイズが小さいですよね。。。
VisualC++は、main関数が呼ばれる前に、なにやらいろいろ裏でやってるみたいでサイズがやたらバカでかいです(^^;;;