std::string in winapi?
-
hey, macht es sinn bzw ist es irgendwie möglich, std::string in der winapi zu verwenden? ich stoße nämlich permanent auf das problem, dass ich meine strings in char[] umwandeln muss. ich benutze std::string, weil man damit relativ schnell und simpel umgehen kann. char[] nervt mich extrem, deswegen vermeide ich es, so gut es kann. allerdings geht es jetzt nicht mehr, weshalb sich bei mir 2 fragen auftun:
1. Wie kann ich
char szTest[256];in
std::string szTest;umwandeln?
2. Wie kann ich LPVOID durch einen std::string umwandeln?
-
- Ein char-Array kannst du problemlos in einen std::string reinpacken, der umgekehrte Weg ist unwesentlich schwieriger. Wenn du nur konstante Daten an die WinAPI übergeben willst, kannst du mit ]c]c_str()[/c] arbeiten, wenn du dir aus der WinAPI Daten geben lassen willst, brauchst du einen direkteren Zugang:
string titel; titel.resize(100); GetWindowText(myWnd,&titel[0],100);(wobei, für die WinAPI würde ich einen
typedef std::basic_string<TCHAR> tstring;verwenden)- Bei einem LPVOID mußt du selber wissen, was sich hinter dem Zeiger verbirgt. Da gibt es keine Universallösung, wie und wohin du die Daten umwandeln kannst.
-
Wobei std::string in C++03 nicht dieselben Grantien bezüglich zusammenhängenden Speicher und der Zugriff via Adresse des 1. Elementes wie std::vector hat.
Selbstverständlich ist es bei den meisten Implementation in Ordnung &s[0] zu verwenden (s ist ein std::string).Korrekterweise wäre ein std::vector angesagt, aus welchem dann ein std::string erzeugt werden kann.
Simon
-
Auch nicht vergessen: Jede WinAPI-Funktion, die mit einem String arbeitet, gibt es in drei Varianten: Normal, als ANSI und als Unicode, wobei die normale Funktion nur ein Makro auf eine der beiden anderen ist, je nachdem, ob das Unicodemakro gesetzt wurde. Wenn man also sowas schreibt:
std::string message = "Hallo"; MessageBox(NULL, message.c_str(), "Titel", MB_OK);funktioniert das solange, bis man das ganze als Unicodeanwendung laufen lassen will. Dann bringt der Compiler Fehler. Deshalb also drauf achten: So macht man's:
#ifdef UNICODE typedef std::string tstring; #else typedef std::wstring tstring; #endif tstring message = TEXT("Hallo"); MessageBox(NULL, message.c_str(), TEXT("Titel"), MB_OK);
-
So geht's ohne Präprozessorgefrickel:
typedef std::basic_string<TCHAR> tstring;
-
Wenn möglich, könntest du ja auch die Klasse CString aus der ATL benutzen. Dan kannst du per GetBuffer einen nicht konstanten char-Zeiger holen, den du dann mit den WinAPI-Funktionen benutzen kannst.
CString titel; GetWindowText(myWnd,titel.GetBuffer(100),100); titel.ReleaseBuffer();
-
Also aus irgendeinem grund seh ich die lösung nicht, ich hoff jemand kann mir die augen öffnen...
dass ich mit c_str() meinen string für ne messagebox z.b passend machen kann, weiß ich, aber irgendwie komm ich trotzdem nicht drauf klar; ich poste mal fix das konkrete problem:string myString( char szText[256] ) { string sTemp = szText[256]; return sTemp; }
-
Abgesehen davon, daß die Arraygröße in der Parameterliste irrelevant ist, greifst du dir ein Zeichen, das gar nicht mehr zu diesem Array gehört. Versuch's mal damit:
string myString( char szText[256] ) // char* szText hätte den selben Effekt { string sTemp = szText; return sTemp; }
-
oder ganz einfach
string myString(char szText[256]) //ich hätte hier auch char * genommen aber egal { return szText; }Der Konstruktor der std::string Klasse nimmt nämlich jede Art von c-strings an. Korrekt wäre jetzt:
return string(szText);
-
Im Fall der letzen Variante, ist es völlig überflüssig, dazu eine Funktion zu erstellen, da es einfach nichts bringt. Man kann's auch so schreiben:
string myString (szText);Ob man die Funktion nimmt oder den String direkt auf diese Weise erstellt, "kostet" es eine Zeile. Der Unterschied ist, dass der Aufruf der Funktion zusätzlich Zeit beansprucht. Ich habe die Erfahrung gemacht, dass einzeilige Funktionen generell selten Vorteil gegenüber einer direkten Implementierung der Prozedur haben.
-
[Rewind] schrieb:
Ich habe die Erfahrung gemacht, dass einzeilige Funktionen generell selten Vorteil gegenüber einer direkten Implementierung der Prozedur haben.
Die Aussage ist zu pauschal. Du vergisst das Argument der Redundanz. Auch bei einzeiligen Aufgaben ist die Auslagerung in eine Funktion sinnvoll, wenn diese vielfach im Code vorkommen, damit man zukünftige Änderungen nur an einer Stelle machen muss.
-
_matze schrieb:
Du vergisst das Argument der Redundanz.
Tu ich nicht. Meine Aussage bezog sich nicht auf alle Fälle.
-
[Rewind] schrieb:
_matze schrieb:
Du vergisst das Argument der Redundanz.
Tu ich nicht. Meine Aussage bezog sich nicht auf alle Fälle.
Na ja, du hast es aber ziemlich allgemein formuliert. Bei dem Beispiel hier halte ich eine Funktion auch für unsinnig, aber du hast dich nicht offensichtlich darauf bezogen.

-
oder gleich richtig machen
template <class T> std::basic_string<T> safe_string(T const* p) { return p ? std::basic_string<T>(p) : std::basic_string<T>(); }Der Konstruktor von std::basic_string mag nämlich keine NULL Zeiger.
-
_matze schrieb:
[Rewind] schrieb:
Ich habe die Erfahrung gemacht, dass einzeilige Funktionen generell selten Vorteil gegenüber einer direkten Implementierung der Prozedur haben.
Die Aussage ist zu pauschal. Du vergisst das Argument der Redundanz. Auch bei einzeiligen Aufgaben ist die Auslagerung in eine Funktion sinnvoll, wenn diese vielfach im Code vorkommen, damit man zukünftige Änderungen nur an einer Stelle machen muss.
Musst nicht mal Redundanz vorliegen. Eine Funktion kann unter Umständen auch verdeutlichen, was man tun will.
if(!is_released && position == NULL) { // ... } bool is_motor_moving() { return !is_released && position == NULL; } if(is_motor_moving()) { // ... }Die zusätzliche Zeit, welche dazu verbratet wird, ist völlig egal. Gute Kompiler optimieren dies sogar völlig weg. Aber für die Übersicht ist es Gold wert.
Grüssli