Aus Winapi String beschreiben



  • Hallo Forum,

    ich habe bisher nur mit char* gearbeitet und würde gern auf string umstellen. Ich habe versucht dieses Beispiel nachzubauen:
    http://www.c-plusplus.net/forum/viewtopic-var-p-is-1201322.html#1201322

    Hier mein Beispiel. Es soll die Serial der Festplatte ausgelesen werden. Dafür muß ich einen char Buffer der WinApi übergeben.

    class ComputerData1 {
    public:
    	string m_sHDSerial;
    	GetHdSerial();
    }
    
    ComputerData1::GetHdSerial() {
    	DWORD lVolSerialNbr=0;
    	char *cTemp=0;
    
    	GetVolumeInformation( "C:\\", 0, 0, &lVolSerialNbr, 0, 0, 0, 0);
    	cTemp = new char[20]; // C String erstellen
    	ultoa(lVolSerialNbr, cTemp, 10); // Befüllen lassen
    
    	m_sHDSerial = new string(strlen(cTemp)); // C++ String erstellen
    	m_sHDSerial->copy(cTemp, sizeof(cTemp)); // C String in den C++ String kopieren.
    	delete[] cTemp;
    }
    

    Die Fehlermeldungen:

    t:\vs6\asdf\computerdata1.cpp(164) : error C2664: '__thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >(const class std::al
    locator<char> &)' : cannot convert parameter 1 from 'unsigned int' to 'const class std::allocator<char> &'
    Reason: cannot convert from 'unsigned int' to 'const class std::allocator<char>'
    No constructor could take the source type, or constructor overload resolution was ambiguous
    t:\vs6\asdf\computerdata1.cpp(165) : error C2819: type 'std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >' does not have an overloaded member 'operator ->'
    t:\vs6\asdf\computerdata1.cpp(165) : error C2227: left of '->copy' must point to class/struct/union

    Was mache ich falsch?



  • m_sHDSerial ist kein Pointer (string* m_sHDSerial!).
    string(strlen(cTemp)) geht nicht, da kein Konstruktor für size_t (unsigned int) vorhanden ist. Mach' einfach m_sHDSerial = new string(cTemp);



  • hmm nee das hat hier wenig mit cpp zu tun jungs ...

    #if !defined(COMPUTER_DATA_H__INCLUDED)
    #define COMPUTER_DATA_H__INCLUDED
    
    #include <windows.h>
    #include <string>
    #include <sstream>
    
    class ComputerData 
    {
    public:
    	bool			fill_hdd_serial();
    
    private:
    	std::string		m_hddserial;
    };
    
    #endif // COMPUTER_DATA_H__INCLUDED
    
    #include "ComputerData.h"
    
    bool ComputerData::fill_hdd_serial() 
    {
    	unsigned long dwVolSerial = 0;
    	if (GetVolumeInformationA("C:\\", NULL, 0, &dwVolSerial, NULL, 0, NULL, 0) == FALSE) // da wir std::string (ANSI) nehmen, müssen wir auch sichergehen, ads wir auch die ANSI-Funktion nehmen ...
    		return false;
    
    	std::ostringstream ss;
    	ss << dwVolSerial;
    	m_hddserial = ss.str();
    
    	return true;
    }
    

    ... so ist das C++ und korrekt 🙂



  • Ich bin tatsächlich dabei von C auf C++ umzusteigen. Vielen Dank (D)Evil



  • (D)Evil schrieb:

    so ist das C++ und korrekt 🙂

    Na ja. Wenn Du jetzt noch den komischen Erfolgs-Rückgabewert weglässt und stattdessen mit Ausnahmen arbeitest, ist es *richtiges* C++. 😉



  • Jetzt auch noch den Rückgabewert weglassen. Ihr verlangt wirklich viel *g*



  • Gibt es keine Möglichkeit zu dem Befehl in dem Catchblock zurückzukehren wo die Exception geworfen wurde? Sowas wie unter VB: "Resume" oder "Resume Next"
    http://tutorial.schornboeck.net/exceptions.htm

    Wenn das nicht geht, was das Tutorial nahelegt, sollte man für behandelbare Fehler vielleicht doch den Rückgabewert und eine if() Klausel in der aufrufenden Funktion verwenden?



  • ZubX schrieb:

    Gibt es keine Möglichkeit zu dem Befehl in dem Catchblock zurückzukehren wo die Exception geworfen wurde? Sowas wie unter VB: "Resume" oder "Resume Next"

    Nein. Generell ergibt es auch keinen Sinn, in die Situation vor dem Fehler zurückkehren zu wollen. In VB6 habe ich zwar auch oft 'Resume Next' eingesetzt, aber außerhalb von VB6 habe ich es eigentlich noch nie gebraucht.

    Wenn das nicht geht, was das Tutorial nahelegt, sollte man für behandelbare Fehler vielleicht doch den Rückgabewert und eine if() Klausel in der aufrufenden Funktion verwenden?

    Nein. Generell weiß eine aufgerufene Routine nie, wo Fehler, die sie auslöst, behandelt werden sollen/können. Ein Rückgabewert ist daher selten sinnvoll, denn der müssgte sonst durchgereicht werden.

    -- Wozu brauchst Du denn 'Resume Next'?



  • Nach dem Schema von FillHDSerial wollte ich mehrere Funktionen bauen die bestimmte Werte ermitteln. Wenn ein Fehler auftritt soll in der Catch Kalusel ein cout gemacht werden und mit der nächsten Anweisung fortgefahren werden.

    Am besten ich lasse das mit Try/Catch wieder.


Anmelden zum Antworten