Resourcen und 64 Bit Programm
-
Hallo,
ich habe eine 64 Bit Dll in der ich ein String Table habe und die Strings zur Laufzeit dynamisch über FindResource und LoadResource lade. Nun funktionierte das unter Win32 und einer 32 Bit DLL ganz wunderbar, mit Win64 und einer 64 Bit DLL schlägt FindResource fehl und auch LoadString geht nicht. GetLastError sagt 1812, Resource nicht gefunden. Weiß jemand was ich ändern muss damit es auch für 64 Bit funktioniert? Hier mal kurz der Testcode der nicht funktioniert:
wchar_t *buf = new wchar_t[256]; LoadString (hModule, (iID / 16) +1, buf, 256); MessageBox (NULL, buf, L"String", MB_OK); delete [] buf; HRSRC hRes = FindResourceW (hModule, MAKEINTRESOURCEW((iID / 16) +1), RT_STRING); if (hRes != NULL) { pwchMem = reinterpret_cast<wchar_t*> (LoadResource (hModule, hRes)); if (pwchMem != NULL) { pwchCur = pwchMem; for (int i = 0; i < 16; i++) { if (*pwchCur != NULL) { int cchString = *pwchCur; // String ength in characters pwchCur++; if (i == strIndex) { // String was found in string table strWide.~basic_string(); strWide.insert (0, pwchCur, cchString); FreeResource (pwchMem); return; } pwchCur += cchString; } else pwchCur++; } } } else { err.NewError (EXCEPTION, L"FindResource failed, Settings::FindStringW", L"%x (hModule), %i (iID), RT_STRING %d", hModule, iID, GetLastError()); }
-
Okay habs selbst herausgefunden. Mein Module-Handle war falsch, da es aus einer für 64 Bit zu kleinen Variablen gelesen wurde.
-
strWide.~basic_string();

-
eek schrieb:
strWide.~basic_string();

Das kommt daher, dass davor auch schon etwas in strWide stehen könnte und ich damit den Speicher davon freigebe. Würde ein clear ebenfalls den Speicher freigeben, ich glaube nämlich nicht?!
-
Dann ist aber der implizite Aufruf des Destruktors absolut falsch!
BTW:
1. Es gibt doch einen Konstruktor der Zeiger und Länge annimmt. Da muss man doch nicht insert verwenden.
2. Warum verwendest Du nicht direkt LoadString?
-
Martin Richter schrieb:
Dann ist aber der implizite Aufruf des Destruktors absolut falsch!
BTW:
1. Es gibt doch einen Konstruktor der Zeiger und Länge annimmt. Da muss man doch nicht insert verwenden.
2. Warum verwendest Du nicht direkt LoadString?Nunja, etwas komplizierter ist es schon. strWide existiert schon die gesamte Zeit und es steht irgendein String drin welcher meinetwegen auch 1 mio. Zeichen lang sein kann. Der Code ergibt sich aus meiner folgenden Erfahrung (könnte natürlich auch nicht ganz richtig sein): ein clear gibt den Speicherplatz nicht wieder frei , im Gegensatz zum Aufruf des Destruktors. Da ich die Stringlänge dynamisch ermitteln möchte (deshalb verwende ich auch nicht LoadString) kann ich bei insert die Länge mit angeben. Ein strWide = pwchCur funktioniert nicht, da er teilweise über das Ende des String hinaus liest.
Edit: Oder wie wäre es denn richtig?
-
http://www.cpptalk.net/speicher-von-vector-freigeben-vt24712.html
Sollte auch mit String gehen...
-
Das direkte zuweisen sollte auch gehen.
Das meinte ich mit Konstruktor:strwide = wstring(pchChar,iLen);Deine Methode ist absolut verboten. Dein Objekt wird dadurch zersört und unbenutzbar. Nehmen wir nur mal an in dem std::string Objekt wäre ein Zeigerauf einen Allokator mit gespeichert... Der Aufruf des Destruktors und anschließend das weiter Benutzen des Objektes ist absolut falsch!
-
Okay, hab es zu
std::wstring().swap (strWide); strWide = std::wstring (pwchCur, cchString);geändert. Stimmt das jetzt so? Danke für den Hinweis!
-
Ich würde nur die Zuweisung schreiben. Das ist insgesamt sicherlich optimaler.
Bist Du wirklich sicher, dass Du unbedingt den Sepicher freigeben musst? Wenn der genutzte Speicher wieder verwendet wird ist die Zuweisung weitaus effektiver.
-
Doch ist in meinem Fall schon besser den Speicher freizugeben. Auf Performance koommt es bei mir nicht an.