• 从Win32程序中的主函数中获取命令行参数


    【翻译文章,原文来自:http://codingmisadventures.wordpress.com/2009/03/10/retrieving-command-line-parameters-from-winmain-in-win32/

    在标准C或者Win32控制台程序的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: Variables __argc and __argv

    另外,微软提供了全局变量__argc 和__argv。这两个变量由Windows在运行时自动赋值。其中__argv有ASCII和Unicode版本,分别为__argv和__wargv。要使用这两个全局变量,需要引用"stdlib.h"头文件(该头文件已经在windows.h中引用)。为了根据工程设置来自动选择ASCII还是Unicode版本变量,我们可以引用"TCHAR.h"头文件并访问__targv变量。代码如下

    extern int __argc;

    extern TCHAR* __targv;

    这个方法是所有方法中最简单的一个。但它的代价是程序需要链接VC++运行时库(例如"msvcrt.dll")。当然99%的Windows程序几乎都要使用这个运行库:)

    Del.icio.us : 命令行参数 WinMain

  • 相关阅读:
    [LC] 939. Minimum Area Rectangle
    [LC] 1110. Delete Nodes And Return Forest
    [LC] 1057. Campus Bikes
    [LC] 528. Random Pick with Weight
    [LC] 341. Flatten Nested List Iterator
    oracle获取本月第一天和最后一天及Oracle trunc()函数的用法
    监控concurrent 正在执行的sql
    UTL_FILE 的用法
    查询EBS在线用户SQL(R12)
    ORACLE EBS BOM 展开(使用标准程序bompexpl.exploder_userexit展开)
  • 原文地址:https://www.cnblogs.com/xuguilin/p/1858970.html
Copyright © 2020-2023  润新知