Begriffserklärungen und Fragen



  • was sind PCHAR und LPTSTR für Datentypen?wo liegen ihre unterschiede?
    liegt der unterschied zu DWORD und INT32 nur daran, das INT32 auch negative werte annehmen kann?
    Ist ein Hkey ein spezeieller handle?eben einer der nur für regkeys verwendet wird?

    warum definiert die win api eigene datentypen?

    danke



  • zumindest deren definierung kann ich dir auflisten.
    wenn du in die jeweiligen .h dateien reinschaust, siehst du, dass die von nem haufen #ifndef #define umgeben sind.

    winnt.h

    typedef CHAR *PCHAR, *LPCH, *PCH;

    tchar.h

    typedef char TCHAR;

    wtypes.h

    typedef /* [string] */ TCHAR *LPTSTR;


  • Mod

    ameise schrieb:

    was sind PCHAR und LPTSTR für Datentypen?wo liegen ihre unterschiede?

    PCHAR == char*
    LPTSTR == TCHAR *
    TCHAR ist abhängig von de Projekteinstellung für den Zeichensatz! Entweder wchar_t in Unicdoe Projekten oder eben char.

    ameise schrieb:

    liegt der unterschied zu DWORD und INT32 nur daran, das INT32 auch negative werte annehmen kann?

    Ja!

    ameise schrieb:

    Ist ein Hkey ein spezeieller handle?eben einer der nur für regkeys verwendet wird?

    Soweit ich weiß ja.

    ameise schrieb:

    warum definiert die win api eigene datentypen?

    Tut die Windows API das? Es sind doch nur Definitionen für interne Typen (DWORD etc.)
    Diese Definitionen sind so gewählt, damitman eben die Compiler Unterschiede ausgleichen kann. int/long sind eben nicht definiert wie groß sie sind.

    Bei Handles ist das wohl auch klar:
    Damit man eben Handles und Werte nicht wahlfrei vertauschen kann. Damit ist wenigestens einigermaßen gewährleistet, dass ein Programmierer keinen HKEY Wert für SetWindwText nutzt...



  • Martin Richter schrieb:

    Tut die Windows API das? Es sind doch nur Definitionen für interne Typen (DWORD etc.)
    Diese Definitionen sind so gewählt, damitman eben die Compiler Unterschiede ausgleichen kann. int/long sind eben nicht definiert wie groß sie sind.

    So intern sind die gar nicht. Sie kommen in den Parmeterlisten der Funktionen vor und werden auch zurückgegeben.

    Wenn ich schreibe:
    typedef unsigned long DWORD;
    

    Habe ich damit die Größe definiert, da doch die Größe von long undefiniert ist ?


  • Mod

    Die Header sind so gebaut, das sie für die gängigen 32bitund 64bit Compiler funktionieren.



  • Martin Richter schrieb:

    Die Header sind so gebaut, das sie für die gängigen 32bitund 64bit Compiler funktionieren.

    Ja, aber as würde doch auch ohne diese im Grunde überflüssigen typedefs gehen.


  • Mod

    w. schrieb:

    Martin Richter schrieb:

    Die Header sind so gebaut, das sie für die gängigen 32bitund 64bit Compiler funktionieren.

    Ja, aber as würde doch auch ohne diese im Grunde überflüssigen typedefs gehen.

    Welche typedefs sind überflüssig?
    Wie will man ohne DWORD auskommen, das compilerspezifisch den richtigen Typ wählt?

    Nein! IMHO nicht. Schon gar nicht, wenn man berücksichtigt, dass das die Win32 API ihre Wurzeln hat in Zeiten wo von einer Standardisierung keine Rede sein konnte.
    Und zu den Zeiten war ein int noch 16bit! 😉



  • Du hast es doch selbst geschrieben:

    Die Header sind so gebaut, das sie für die gängigen 32bitund 64bit Compiler funktionieren.

    Da ist doch ein typedef unsigned long DWORD; redundant, bzw. überflüssig.
    Oder verstehe ich da etwas falsch.


  • Mod

    Wieso? Einem Compiler steht es doch frei ein long auch 64bit weit zu machen.

    Ein DWORD ist immer ein 32bit unsigned int!



  • typedef unsigned long DWORD;

    Ein DWORD ist sizeof(unsigned long) * CHAR_BIT Bits weit.

    Sollte unsigned long 8 Bytes groß sein und CHAR_BIT gleich 8 sein , kommen wir auf Summa Summarum 64 Bit.



  • Unter Windows ist ein unsigned long immer vier Bytes groß und nicht acht.



  • sri schrieb:

    Unter Windows ist ein unsigned long immer vier Bytes groß und nicht acht.

    die breite von 'long', ob signed oder unsigned, kann ein compiler innerhalb gewisser grenzen selbst bestimmen. der eine compiler nimmt 32, der andere z.b. 64 bits dafür. weil windoofs aber gern an gewissen stellen 32 bit breite datentypen sehen will, kann DWORD bei compiler A als 'unsigned int' definiert sein, bei compiler B jedoch nicht, weil das zu viel des guten wäre. da nimmt man einen anderen primitiven typ, z.b. 'unsigned short', der 32 bits gross ist.
    🙂



  • sind typedefs und können von System zu System unterschiedlich sein. Ursprünglich war das mal so gedacht:

    short 16 Bit
    int 32 Bit
    long "was halt so geht" Bit

    Mal sehen, ob ich recht habe ...

    Testobject: sizeType = sizeof(type); (ist dann die Anzahl Bytes)
    auf: s.u.
    mit: VS 08 Expr.

    sizeShort 2 Byte
    sizeInt 4 Byte
    sizeLong 4 Byte (auf einem Intel Celeron, jaja ich weiss... olle Krücke)

    Daraus ist direkt ersichtlich, waraum man unter Win32 mit simplen Deklarationen wie

    long aVar;

    Probleme bekommen kann, wenn portiert werden soll. Wenn Win32-Programmierung, dann auch die zur Verfügung gestellten Datentypen (U)SHORT oder (U)LONG benutzen! int (Win32: INT/UINT) hingegen sollte IMMER 32 Bit sein (per Ansi-Norm, bitte auf 64 BitMaschine testen).
    Der jeweilige typedef für ULONG oder USHORT wird unter VS xyz angezeigt, wenn mann nicht gerade debuggt und den Mauszeiger über dem Typ platziert.

    Gruß

    Lars



  • danke soweit! wieso wird der 2. satz nicht ausgegeben?

    #include <windows.h>	// HANDLE, DWORD,.. AllocConsole, GetStdHandle,.. 
    #include <string.h>		// strlen
    #include <stdio.h>		// puts
    
    int main (int argc, LPTSTR argv[])
    {
    	HANDLE hOut;
    	DWORD nWrite, nWritten;
    	CHAR buffer[] = "text hier \n";  // ;-)
    
    	// Konsole vorbereiten
    	AllocConsole();										//Weist dem aufrufenden Prozess eine Konsole zu 
    	hOut = GetStdHandle(STD_OUTPUT_HANDLE);				//Gibt einen Handle auf standard input, output oder error 
    
    	// Laenge des Textes bestimmen
    	nWrite = (DWORD) strlen(buffer);
    
    	// Konsolenausgabe
    	WriteConsole(
    		hOut,       // handle to screen buffer
    		buffer,		// write buffer
    		nWrite,     // number of characters to write
    		&nWritten,  // number of characters written
    		NULL        // reserved
    	);
    
    	// Konsole schliessen
    		CloseHandle(hOut);
    	FreeConsole();
    
    	puts("Warum wird dieser Text nicht ausgegeben?");
    
    	return 0;
    
    }
    

    ok für den ersten satz wird die api benutzt, aber danach könnte ich doch ganz normal mit meinen c libraries arbeiten oder?



  • ameise123 schrieb:

    danke soweit! wieso wird der 2. satz nicht ausgegeben?

    Weil Du das Standard-Ausgabehandle schließt?



  • den brauch ich doch sonst auch nicht?!?! für puts reicht doch einbinden der entsprechenden bibliothek!


  • Mod

    ameise123 schrieb:

    den brauch ich doch sonst auch nicht?!?! für puts reicht doch einbinden der entsprechenden bibliothek!

    Witzbold!
    Und was glaubst Du was für eine Funktion puts verwendet?
    Was glaubst Du wohin puts letzten Endes ausgibt?
    Jaaaaa genau, die Antwort lautet: Auf das STD_OUTPUT_HANDLE!
    Und was hast Du gemacht?
    Genau: Du hast es geschlossen?
    Letzte finale Frage: Wie soll nun puts etwas ausgeben?



  • ja die c library greift auf die win32api zu und dort müsste sie doch dann einen neuen handle anlegen, sobald ich puts aufrufe?!?!
    ich schließe doch nur den einen handle, den hout, aber ich könnte doch jederzeit einen neuen erstellen?!?



  • "A process can be associated with only one console." Und die hast du dicht gemacht. Was passiert, wenn du puts("Warum wird dieser Text nicht ausgegeben?"); vor CloseHandle(...) setzt?
    Mit der Bitte um Antwort.


  • Mod

    ameise123 schrieb:

    ja die c library greift auf die win32api zu und dort müsste sie doch dann einen neuen handle anlegen, sobald ich puts aufrufe?!?!
    ich schließe doch nur den einen handle, den hout, aber ich könnte doch jederzeit einen neuen erstellen?!?

    Ahhh. Du erwartest also, dass die CRT Deine Fehler ausbügelt. 🤡

    Nun denn: Woher soll denn in den tiefsten tiefen der CRT aufeinmal wieder gewusst werden welches Ausgabehandle der Console (evtl. wurde es ja umgelenkt) zu nutzen ist. Machen wir also einfach "irgendein" neues auf?

    Es ist so wie chezzmatazz schreibt. Du bekommst EIN Handle für die Ausgabe in Deinem Prozess. Dieses benutzt die CRT auch. Du hast es geschlossen. Damit ist die Verbindung weg.
    Man hätte ja auch kein deterministisches Verhalten mehr, wenn die CRT mal so intern noch ein paar Kopien auf die Handles vorhalten würde.

    Grundsätzliche Frage: Warum mischt Du CRT und Konsolenfunktionen? IMHO unnötig. Entweder nimmt man das eine, oder das andere.



  • ja is klar das ich nur das eine oder das andere nehme, aber man muss halt auch mal verstehen wie beides zusammen harmoniert oder eben nicht. Also reines interesse an der art und weise wie das ganze funktioniert!


Anmelden zum Antworten