Typenfrage



  • Hallo zusammen..
    Ich habe eine kurze Frage zu folgender Funktion:

    BOOL GetComputerName(
    
        LPTSTR lpBuffer,	// address of name buffer 
        LPDWORD nSize 	// address of size of name buffer 
       );
    

    Als Typen für die Paramter werden LPTSTR und LPDWORD angegeben. Wenn ich das richtig verstanden habe, ist LPTSTR ein Aliasname für wchar_t* und LPDWORD ein Aliasname für unsigned long*.

    Erste Frage:
    Ist es dann egal, ob ich LPTSTR oder wchar_t* schreibe? Ich bekomme unterschiedliche fehlermeldungen und das irritiert mich da etwas.

    Zweite Frage:
    Bisher habe ich die Funktion so genutzt:

    TCHAR buffer[255];
    	DWORD size = sizeof(buffer);
    
    	GetComputerName(buffer, &size);
    

    So habe ich es irgendwo im Internet mal gefunden. _Meine_ Version funktionierte nämlich nicht:

    LPTSTR buffer;
    	LPDWORD size = sizeof(buffer);
    
    	GetComputerName(buffer, &size);
    

    Für die meisten von euch wird das sicherlich etwas schräg aussehen und auch klar sein, wieso das nicht geht. Mir ist das aber ganz und garnicht klar. Wenn in dem Funktionsprototypen steht, dass die Parameter vom Typ LPTSTR und LPDWORD sind, dann benutze ich diese Typen doch auch beim Aufruf der Funktion oder sehe ich da etwas komplett falsch?



  • ad TCHAR:
    TCHAR (und seine Stringdefinitionen LPTSTR, LPCTSTR usw.) ist je nach Build-Modus ein char (ANSI-Modus) oder ein wchar_t (UNICODE-Modus). Das heisst wenn Du konsequent TCHAR (statt char oder wchar_t), LPTSTR (statt LPSTR und LPWSTR) sowie LPCTSTR (statt LPCSTR und LPCWSTR) verwendest, kannst Du die Zeichenbreite im gesamten Programm mit einem Compilerswitch umschalten. Damit lautet die Antwort auf die erste Frage: Es ist nicht optimal, weil dadurch der Vorteil verlorengeht, und darüberhinaus ist es nur dann egal wenn du im UNICODE-Modus übersetzt.

    Zur zweiten Frage:
    Deine Version legt einen uninitialisierten Zeiger namens buffer an und weist size die Größe dieses Zeigers zu. Damit schreibt die Funktion GetComputerName hoffnungslos in Speicher, der Dir nicht gehört. Die Funktionierende Variante legt einen Buffer von 500 Zeichen Länge auf dem Stack an und speichert dessen Größe in size. Damit kann GetComputerName in gültigem Speicher den Rechnernamen ablegen.

    EDIT:
    Huch, dass size selbst noch ein Zeiger ist habe ich ja ganz übersehen (dazu siehe CStolls Beitrag unter meinem).



  • Andy_B_ schrieb:

    Hallo zusammen..
    Ich habe eine kurze Frage zu folgender Funktion:

    BOOL GetComputerName(
    
        LPTSTR lpBuffer,	// address of name buffer 
        LPDWORD nSize 	// address of size of name buffer 
       );
    

    Als Typen für die Paramter werden LPTSTR und LPDWORD angegeben. Wenn ich das richtig verstanden habe, ist LPTSTR ein Aliasname für wchar_t* und LPDWORD ein Aliasname für unsigned long*.

    LPTSTR ist TCHAR* (und TCHAR ist je nach Konfiguration entweder char oder wchar_t), LPDWORD ist DWORD* (auf welchen int-Typ das übersetzt wird, hängt vom System ab)

    Zweite Frage:
    Bisher habe ich die Funktion so genutzt:

    TCHAR buffer[255];
    	DWORD size = sizeof(buffer);
    
    	GetComputerName(buffer, &size);
    

    So habe ich es irgendwo im Internet mal gefunden. _Meine_ Version funktionierte nämlich nicht:

    LPTSTR buffer;
    	LPDWORD size = sizeof(buffer);
    
    	GetComputerName(buffer, &size);
    

    Ein "LPDWORD" ist ein Zeiger auf eine DWORD-Variable - dem kannst du erstens keinen nackten Wert zuweisen und zweitens kommt nichts passendes heraus, wenn du dessen Adresse nimmst. Ausgeschrieben könntest du die Funktion auch so verwenden:

    LPTSTR buffer = new TCHAR[255];//hier mußt du ausreichend Speicher bereitstellen
    DWORD size=255;
    LPDWORD ptr = &size;//hole die Adresse von 'size'
    GetComputerName(buffer,ptr);
    

    (die Hilfsvariable ptr kann weggelassen werden und anstelle des dynamisch angelegten Arrays kannst du ein Stack-Array verwenden (wird beim Aufruf implizit in einen Zeiger umgewandelt) und schon bist du bei der ursprünglichen Version.



  • Vielen Dank euch beiden. Das hat mir sehr geholfen. Jetzt wird mir einiges klarer.


Anmelden zum Antworten