CommandLineToArgvA wskaźniki

0

Witam!
Znalazłem funkcję która parsuje elementy commandline z WinMain, oto ona:

PCHAR *
CommandLineToArgvA(
PCHAR CmdLine,
int * _argc
)
{
    PCHAR * argv;
    PCHAR _argv;
    ULONG len;
    ULONG argc;
    CHAR a;
    ULONG i, j;
    
    BOOLEAN in_QM;
    BOOLEAN in_TEXT;
    BOOLEAN in_SPACE;
    
    len = strlen( CmdLine );
    // ---------------------------------- START ----------------------------------------------
    i =(( len + 2 ) / 2 ) * sizeof( PVOID ) + sizeof( PVOID );
    
    argv =( PCHAR * ) GlobalAlloc( GMEM_FIXED,
    i +( len + 2 ) * sizeof( CHAR ) );
    
    _argv =( PCHAR )((( PUCHAR ) argv ) + i );
    // ---------------------------------- END ------------------------------------------------
    
    argc = 0;
    argv[ argc ] = _argv;
    in_QM = FALSE;
    in_TEXT = FALSE;
    in_SPACE = TRUE;
    i = 0;
    j = 0;
    
    while( a = CmdLine[ i ] ) {
        if( in_QM ) {
            if( a == '\"' ) {
                in_QM = FALSE;
            } else {
                _argv[ j ] = a;
                j++;
            }
        } else {
            switch( a ) {
            case '\"':
                in_QM = TRUE;
                in_TEXT = TRUE;
                if( in_SPACE ) {
                    argv[ argc ] = _argv + j;
                    argc++;
                }
                in_SPACE = FALSE;
                break;
            case ' ':
            case '\t':
            case '\n':
            case '\r':
                if( in_TEXT ) {
                    _argv[ j ] = '\0';
                    j++;
                }
                in_TEXT = FALSE;
                in_SPACE = TRUE;
                break;
                default:
                in_TEXT = TRUE;
                if( in_SPACE ) {
                    // ---------------------------------- START ----------------------------------
                    argv[ argc ] = _argv + j;
                    // ---------------------------------- END ------------------------------------
                    argc++;
                }
                _argv[ j ] = a;
                j++;
                in_SPACE = FALSE;
                break;
            }
        }
        i++;
    }
    _argv[ j ] = '\0';
    argv[ argc ] = NULL;
    
    ( * _argc ) = argc;
    return argv;
}

Nie rozumiem paru linijek kodu, które zamieszczone są w tej funkcji, a mianowicie bloków START-END.
Pierwszy blok - dlaczego do zmiennej i przypisywana jest taka wartość? Później jest ona wykorzystywana do alokacji pamięci ( czy aby nie za dużo pamięci zostaje przydzielone? ) zmiennej argv. Końcówki bloku również nie rozumiem, a mianowicie przypisania do _argv ( alokacji pamięci? ) zmiennej argv...
Drugi blok zaś składa się tylko z jednej linijki ( powtarza się kilka razy ). Czy to jakiś ogranicznik w sensie - do którego momentu dane mają być kopiowane? Gdy dam prinf( "%s\n", _argv ); po i++, ( gdy włączę program przez CMD i przekaże parametry ), to wyświetla tylko nazwę programu, żadnych dodatkowych parametrów które zostały przekazane ( choć funkcja je wydzieliła poprawnie, bo są w tablicy )...

Chcę tylko zrozumieć jak to działa. Dzięki z góry.
O wskaźnikach czytałem tutaj: http://pl.wikibooks.org/wiki/C/Wskaźniki_-_więcej

1

Ad 1. Przydzielanie pamięci jedno na wszystko, na kopię parametrów _argv oraz na tablicę wskaźników argv
Ad 2. Wpisanie w kolejny element tablicy wskaźnika przesuniętego o j znaków - początek kolejnego parametru.

0

Wielkie dzięki :) ( a wyświetla tylko nazwę programu bez dodatkowych parametrów, ponieważ po każdym jest znak \0 - zrozumiałem to wyświetlając znaki pojedynczo :D )

1

Kod wywalić, użyć wbudowanego w system CommandLineToArgvW i używać unikodu.

1

Tak chciałem zrobić, jednak niestety nie mogę - mam swoje powody.
Tutaj chciałem się dowiedzieć jak to działa i udało się.

0

pozwolę sobie nie zgodzić się z „twoimi powodami”, ale nawet jeśli, to możesz użyć funkcji CommandLineToArgvW i przekonwertować wyjście do ascii.
przynajmniej będziesz miał zachowanie zgodne z funkcją systemową.

1 użytkowników online, w tym zalogowanych: 0, gości: 1