LoadString-Problem



  • Hallo,

    ich habe folgenden C++-Code geschrieben:

    #include <iostream>
    #include <stdlib.h>
    #include <string.h>
    #include <windows.h>
    
    using namespace std;
    
    int main (void) {
    	string pDLL = "D:\\TEST.dll";
    	HMODULE hDLL = LoadLibrary (pDLL.c_str());
    	HRSRC fRes = FindResource (hDLL,MAKEINTRESOURCE (1),MAKEINTRESOURCE (6));
    	HGLOBAL lRes = LoadResource (hDLL,fRes);
    	LockResource (lRes);
    	LPTSTR stringRes;
    	int checkRes = LoadString (hDLL,1,stringRes,sizeof (stringRes));
    	FreeLibrary (hDLL);
    	cout << hDLL << "\n" << fRes << "\n" << lRes << "\n" << checkRes << "\n" << stringRes << "\n\n";
    	system ("pause > NUL");
    	return 0;
    };
    

    Warum stürzt das Programm ab, kurz nachdem ich es gestartet habe? Der Kompiler (g++.exe von MinGW) erkennt keine Fehler.
    In der DLL-Datei "TEST.dll" habe ich einfach mit dem XN Resource Editor eine String-Tabelle erstellt, bei dem die ID's 0,1,2 und 3 mit einer Zeichenkette belegt sind. Warum aber der Absturz?

    Danke im Voraus!

    MfG

    Seikuassi



  • ...



  • Aha, also LPTSTR gibt maximal 4 Byte (32 Bit) Speicher frei. Das würde ja auch 4 Buchstaben entsprechen. Jetzt habe ich folgenden Code ausprobiert:

    #include <iostream>
    #include <stdlib.h>
    #include <string.h>
    #include <windows.h>
    
    using namespace std;
    
    int main (void) {
    	string pDLL = "D:\\TEST.dll";
    	HMODULE hDLL = LoadLibrary (pDLL.c_str());
    	HRSRC fRes = FindResource (hDLL,MAKEINTRESOURCE (1),MAKEINTRESOURCE (6));
    	HGLOBAL lRes = LoadResource (hDLL,fRes);
    	LockResource (lRes);
    	LPTSTR stringRes [2048];
    	LoadString (hDLL,1,stringRes,sizeof (stringRes));
    	FreeLibrary (hDLL);
    	cout << hDLL << "\n" << fRes << "\n" << lRes << "\n" << stringRes << "\n\n";
    	system ("pause > NUL");
    	return 0;
    };
    

    Allerdings bekomme ich folgenden Fehler vom Compiler:

    [Error] cannot convert 'CHAR** {aka char**}' to 'LPSTR {aka char*}' for argument '3' to 'int LoadStringA(HINSTANCE, UINT, LPSTR, int)'
    (15|49)

    Es muss doch irgendwie möglich sein, LPTSTR zu "vergrößern" also ein Array mit Daten zu befüllen. Wie muss ich vorgehen?

    Danke im Voraus!

    MfG

    Ph. Buchmann



  • LPTSTR stringRes [2048];
    

    Das gibt dir 2048 leere Strings. Du willst aber glaube ich einen String mit 2048 Zeichen. Der Compiler meckert berechtigterweise, dass er keinen String in ein Array von Strings tun kann.
    Vielleicht willst du

    TCHAR stringRes[2048];
    


  • ...



  • Vielen Dank nwp3! Jetzt die letzte Frage:
    Warum TCHAR und nicht LPTSTR? Es ist also das Gleiche, als wenn man char x [1000] und string x [1000] schreiben würde. Der String beinhaltet also 1000 Strings 😮 ? Warum kann man jetzt aber einen LPTSTR in ein TCHAR umwandeln? Einen string in ein char umzuwandlen geht zwar, aber ich brauche doch externe Befehle.

    Bei den Kommentaren (remarks) von MSDN steht sogar, dass man einen TCHAR nehmen soll.

    For example, if lpBuffer points to a buffer szBuffer which is declared as TCHAR szBuffer[100], then sizeof(szBuffer) gives the size of the buffer in bytes, which could lead to a buffer overflow for the Unicode version of the function.

    Vielen Dank nochmal für eure Hilfe!

    MfG

    Ph. Buchmann



  • Hallo nochmal,

    habe gerades ein weiteres "Problem" entdeckt. Zuerst den Code, den ich die ganze Zeit benutzt habe:

    #include <iostream>
    #include <stdlib.h>
    #include <string.h>
    #include <windows.h>
    
    using namespace std;
    
    int main (void) {
    	string pDLL = "D:\\TEST.dll";
    	HMODULE hDLL = LoadLibrary (pDLL.c_str());
    	HRSRC fRes = FindResource (hDLL,MAKEINTRESOURCE (1),MAKEINTRESOURCE (6));
    	HGLOBAL lRes = LoadResource (hDLL,fRes);
    	LockResource (lRes);
    	TCHAR stringRes[2048];
    	LoadString (hDLL,1,stringRes,sizeof (stringRes));
    	FreeLibrary (hDLL);
    	cout << hDLL << "\n" << fRes << "\n" << lRes << "\n" << stringRes << "\n\n";
    	system ("pause > NUL");
    	return 0;
    };
    

    Der String mit der ID "1" wird ohne Probleme angezeigt. Wenn ich jetzt aber

    #include <iostream>
    #include <stdlib.h>
    #include <string.h>
    #include <windows.h>
    
    using namespace std;
    
    int main (void) {
    	string pDLL = "D:\\TEST.dll";
    	HMODULE hDLL = LoadLibrary (pDLL.c_str());
    	HRSRC fRes = FindResource (hDLL,MAKEINTRESOURCE (2),MAKEINTRESOURCE (6));
    	HGLOBAL lRes = LoadResource (hDLL,fRes);
    	LockResource (lRes);
    	TCHAR stringRes[2048];
    	LoadString (hDLL,1,stringRes,sizeof (stringRes));
    	FreeLibrary (hDLL);
    	cout << hDLL << "\n" << fRes << "\n" << lRes << "\n" << stringRes << "\n\n";
    	system ("pause > NUL");
    	return 0;
    };
    

    eingebe, zeigt er mir noch den ersten String an ("String1"). Warum zeigt er keine anderen Strings mehr an, außer den, mit der ID "1"?

    Hier das Bild meines Resource Editors (besser gesagt de .dll):

    [url]
    http://www.fotos-hochladen.net/uploads/resource8fb7sk6xjy.jpg
    [/url]

    Danke im Voraus!

    MfG

    Seikuassi



  • ...



  • Deine Antwort kam, als ich noch meine Antwort geschrieben habe... 🙄



  • Schau dir mal die Parameter deiner Aufrufe von LoadString() an ...

    Ich geh' dann mal in die nächste Ecke... 🙄
    Manchmal sind die Probleme einfach zu klein, dass man (oder besser gesagt ich 🙄 ) diese gar nicht sieht.

    Also vielen Dank nochmal für eure Kooperation 😉 .

    Mein aktueller Code ist nun um einiges kleiner:

    #include <iostream>
    #include <stdlib.h>
    #include <string.h>
    #include <windows.h>
    
    using namespace std;
    
    int main (void) {
    	string pDLL = "D:\\TEST.dll";
    	HMODULE hDLL = LoadLibrary (pDLL.c_str());
    	TCHAR stringRes[2048];
    	LoadString (hDLL,2,stringRes,sizeof (stringRes));
    	FreeLibrary (hDLL);
    	cout << stringRes << "\n\n";
    	system ("pause > NUL");
    	return 0;
    };
    

    Allerletzte Frage: WIe kann ich ein TCHAR in ein char umwandeln? Und wo stehen eigentlich die ganzen Datentypen näher erläutert ( also das ein LPCSTR ein TCHAR* ist usw.)?

    Danke im Voraus!

    MfG

    Seikuassi



  • Nochmal ganz langsam.
    char = Ein ASCII-Zeichen.
    wchar_t = Ein Unicode-Zeichen
    TCHAR = Entweder char oder wchar_t, je nachdem ob Unicode eingeschaltet ist.
    LPCSTR = char * = Ein Pointer auf einen char. Mehrere chars machen einen String. Man braucht aber einen String auf den man den Pointer zeigen lassen kann, sonst ist der ziemlich nutzlos.
    LPWSTR = wchar_t * = dasselbe wie char * nur halt mit Unicode.
    LPTSTR = TCHAR * = char * oder wchar_t * je nach Unicode-Einstellung.
    char[100] = 100 chars. Arrays sind kompatibel zu Pointern, also kann man einem char * ein char[] zuweisen, verliert aber die Information wie viele chars es sind.
    Gleiches gilt für wchar_t[] und wchar_t * und TCHAR[] und TCHAR *.

    Und zu der anderen Frage: Laut der Doku zu LoadString gibt der zweite Parameter die ID an. Wahrscheinlich willst du LoadString(..., 2, ...); in Zeile 15.

    //argh, wieder zu langsam

    Gegenfrage: Warum willst du ein TCHAR in ein char umwandeln? Das willst du bestimmt nicht. Entweder dein TCHAR ist schon ein char, weil Unicode ausgeschaltet ist, oder du benutzt einfach Unicode und sagst wcout << stringRes. Das würde zufällig funktionieren, weil bei dir Unicode eingeschaltet ist, aber eigentlich willst du ein tcout haben was TCHARs ausgeben kann. Das gibts nicht vorgefertigt, aber sieh dir mal die Deklaration von TCHAR an, dann weißt du auch wie du tcout ganz einfach selbst deklarieren kannst.
    Die nächste Möglichkeit ist, dir einfach einen char* geben zu lassen. LoadString gibt es in drei Varianten: LoadStringA für char *, LoadStringW für wchar_t * und LoadString für TCHARs. Wenn du chars willst nimm halt gleich LoadStringA.
    Wenn du super hartnäckig bist kannst du mbstowcs (Multi Byte String TO Wide Character String) bzw. wcstombs benutzen, halte ich aber für überflüssig.



  • ...



  • Hallo,

    @nwp3
    Das C in LPCSTR bedeutet const. Also ist ein LPCSTR ein const char*.



  • Hallo,

    das ist jetzt mein aktueller funktionierender Code, der einen string als Rückgabewert liefert, den ich auf jeden Fall öfters benutze als char benutze:

    #include <iostream>
    #include <stdlib.h>
    #include <string.h>
    #include <windows.h>
    
    using namespace std;
    
    string DLL_String (string pDLL,int id,int count) {
    	HMODULE hDLL = LoadLibrary (pDLL.c_str());
    	char Res [count];
    	LoadString (hDLL,id,Res,count);
    	FreeLibrary (hDLL);
    	string ResCopy = string (Res);
    	return ResCopy;
    };
    int main (void) {
    	string stringRes = DLL_String ("D:\\TEST.dll",10,2048);
    	if ((stringRes != "")) {
    		cout << stringRes << "\n\n" << "[ENDE]";
    		system ("pause > NUL");
    		return 0;
    	};
    	if ((stringRes == "")) {
    		cout << ">> Leerer String << " << "\n\n" << "[ENDE]";
    		system ("pause > NUL");
    		return 1;
    	}
    };
    

    Danke nochmal für eure Hilfe!

    MfG

    Seikuassi



  • ...



  • Hallo Swordfish,

    Error 1 error C2057: expected constant expression d:\swordfish\documents\visual studio 2012\projects\codefun\main.cpp 10
    Error 2 error C2466: cannot allocate an array of constant size 0 d:\swordfish\documents\visual studio 2012\projects\codefun\main.cpp 10
    Error 3 error C2133: 'Res' : unknown size d:\swordfish\documents\visual studio 2012\projects\codefun\main.cpp 10
    7 IntelliSense: expression must have a constant value d:\Swordfish\Documents\Visual Studio 2012\Projects\Codefun\main.cpp 10
    Error 4 error C2678: binary '!=' : no operator found which takes a left-hand operand of type 'std::string' (or there is no acceptable conversion) d:\swordfish\documents\visual studio 2012\projects\codefun\main.cpp 19
    8 IntelliSense: no operator "!=" matches these operands
    operand types are: std::string != const char [1] d:\Swordfish\Documents\Visual Studio 2012\Projects\Codefun\main.cpp 19
    Error 5 error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'std::string' (or there is no acceptable conversion) d:\swordfish\documents\visual studio 2012\projects\codefun\main.cpp 20
    9 IntelliSense: no operator "<<" matches these operands
    operand types are: std::ostream << std::string d:\Swordfish\Documents\Visual Studio 2012\Projects\Codefun\main.cpp 20
    Error 6 error C2678: binary '==' : no operator found which takes a left-hand operand of type 'std::string' (or there is no acceptable conversion) d:\swordfish\documents\visual studio 2012\projects\codefun\main.cpp 24
    10 IntelliSense: no operator "==" matches these operands
    operand types are: std::string == const char [1] d:\Swordfish\Documents\Visual Studio 2012\Projects\Codefun\main.cpp 24

    Vielleicht bekommst du diese Fehlermeldung, weil du Visual Studio benutzt und ich g++.exe vom MinGW. Bei mir funktioniert mein Code einwandfrei.

    [url]
    http://img5.fotos-hochladen.net/uploads/cdllhz2axv0pg7.jpg
    [/url]

    MfG

    Seikuassi



  • ...


Anmelden zum Antworten