Win 32プログラムのメイン関数からコマンドラインパラメータを取得します。

3342 ワード

【翻訳文、原文由来:http://codingmisadventures.wordpress.com/2009/03/10/retrieving-command-line-parameters-from-winmain-in-win32/を選択します
標準CまたはWin 32コンソールプログラムのmain関数には、「argc」と「argv」の二つのパラメータがあります。
int main(int argc, char * argv[]) ...

这些参数帮助我们为程序传入命令行参数。"argc"为命令行参数的个数,"argv"则为传入参数的数组列表。但是当我们在Visual Studio中创建Win32 GUI程序的时候,WinMain变成程序的入口函数,而该函数并没有"argc" 和"argv"参数,那我们怎样给Windows程序传入命令行参数呢?Windows程序中又怎样取得这些传入的参数呢?

lpCmdLine 参数

第一个方案就来自WinMain函数自身。让我们看一个典型的WinMain函数声明:

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)..

如声明所示,WinMain函数有一个类型为"LPSTR(char*)"的参数"lpCmdLine". 这个变量存放着命令行中除程序自身名字外的剩下所有部分。例如,我们有一个名字为"test.exe"的应用程序,当用下面的命令行运行该程序时

test.exe Some arguments here

变量lpCmdLine的值即为"Some arguments here"。尽管该方法不像"argc"和"argv"一样非常方便,但它是获取命令行参数的方法之一。我们需要自己写程序去分析lpCmdLine字符串,这增加了程序的复杂度。

【译注:Windows程序代码同时ANSI版本和UNICODE版本接口。其中WinMain函数为ANSI版本,wWinMain为UNICODE版本。从Visual Studio创建出来的代码主函数命名为_tWinMain。这个函数名会根据当前工程有没有定义_UNICODE宏而在编译时翻译成上面两个不同版本。当翻译成WinMain函数时候,lpCmdLine的类型为LPSTR,而当翻译成wWinMain函数时候,lpCmdLine的类型为LPWSTR,即宽字符数组】

GetCommandLine()函数

另外一个方法就是使用GetCommandLine() API。这个函数返回整个命令行,它把程序自身名称(包括程序的绝对路径)和所有参数放在一个字符串中。该函数非常类似于对lpCmdLine的直接访问。但它的一个好处是能够根据你当前工程的设置自动映射到GetCommandLineA()或者GetCommandLineW()函数。因此解决了访问Unicode命令行输入的问题。但是它还是既没有提供命令行参数数目,也没有类似argv那样把参数自动分割成独立变量的能力。

CommandLineToArgvW()函数

最后一个我要讨论的方法是CommandLineToArgvW函数。这个函数只有Unicode宽字符版本,没有对应的CommandLineToArgvA函数。它的声明如下:

 
  
LPWSTR *CommandLineToArgvW(LPCWSTR lpCmdLine, int *pNumArgs)

该函数和'argc'/'argv'一样简单,但是它并不是在Windows程序中直接访问argc和argv变量。如声明所示,函数接受两个参数,一个是需要解析的Unicode命名行字符串,另外一个是指向整型变量的指针。函数在返回时把参数数目存到这个整型变量中。

函数返回一个类似于'argv'的字符串数组。让我们看一个例子:



int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    LPWSTR *szArgList;
    int argCount;

     szArgList = CommandLineToArgvW(GetCommandLine(), &argCount);
     if (szArgList == NULL)
     {
         MessageBox(NULL, L"Unable to parse command line", L"Error", MB_OK);
         return 10;
     }

     for(int i = 0; i < argCount; i++)
     {
         MessageBox(NULL, szArgList[i], L"Arglist contents", MB_OK);
     }

     LocalFree(szArgList);
     return 0;
}
上記のように、この関数により、コマンドラインパラメータの数(argc)と文字列リスト(argv)を取得することができます。ここで唯一注意すべきことは、この関数がパラメータリストに戻りメモリを割り当てることです。リストを使い終わったら手動でメモリをリリースしないとメモリが漏れます。
EDIT:Varabeles_uargc and_うargv
また、マイクロソフトはグローバル変数(℃)を提供しています。アルクとアルクargvこの二つの変数はWindowsによって実行中に自動的に割り当てられます。そのうちargvにはASCIIとUnicodeのバージョンがあります。それぞれ__uです。アルgvとウウwargvこの二つのグローバル変数を使うには、「stdlib.h」ヘッダファイルを参照する必要があります。プロジェクトの設定によってASCIIまたはUnicodeのバージョン変数を自動的に選択するために、「TCHARR.h」のヘッダファイルを参照して、__uにアクセスすることができます。タリgv変数。コードは以下の通りですextern int __argc;extern TCHAR*_utaltv;
この方法は全ての方法の中で最も簡単なものです。しかし、その対価は、プログラムにはVC++のランタイムライブラリ(例えば「msvcrt.dll」)をリンクする必要があります。もちろん99%のWindowsプログラムはほとんどこのライブラリを使います。
Del.icio.us:コマンドラインパラメータWinMain