Windows API/Compiler/MSDN Doku, Zeiger - Refernezen



  • Das hat so keinen Sinn. Lies ein Buch.



  • Die mit _Out_ gekennzeichneten Parameter sagen Dir, dorthin möchte die Funktion etwas schreiben. Damit sie das kann, benötigt sie einen Zeiger auf einen passenden Speicherbereich.

    Du übergibst aber als Zeiger (Adresse) 0. Dorthin kann die Funktion nicht schreiben.

    Du hast diese zwei Möglichkeiten:

    ...
    DWORD verionWlanApi; // Variable
    WlanOpenHandle (...,...,&verionWlanApi,...); // Zeiger auf den von dieser Variablen belegten Bereich
    

    oder eben:

    ...
    DWORD verionWlanApi; // Variable
    PDWORD  PverionWlanApi=&verionWlanApi;  // Zeiger auf den von dieser Variablen belegten Bereich
    WlanOpenHandle (...,...,PverionWlanApi,...);
    

    ... so, dass der Zeiger auf einen gültigen Bereich zeigt, und nicht auf die Speicherstelle 0.
    Die Funktion schreibt Dir dann was in die Variable verionWlanApi. Bei Deiner Initialisierung des Zeigers mit 0 will die Funktion an die Speicherstelle 0 schreiben, und das kann sie nicht.



  • Du mußt unterschieden, ob es sich bei den Parametern um einen In- oder Out-Parameter handelt (darum steht das in der MSDN auch explizit so drin, obwohl die C Deklaration dies nicht kennt).

    Bei In-Parametern übergibt man gewöhnlich einen einfachen schon initialisierten Zeiger (z.B. den man mittels einer Create-Funktion erhalten hat):

    X *px = CreateX();
    
    FreeX(px); // FreeX(_In_ X*)
    

    Bei einem Out-Parameter initialisiert die Funktion selber den mittels eines Zeigers übergebenen Speicherbereich, d.h. man übergibt dort dann die Adresse einer Variablen:

    X x;
    OpenX(&x); // OpenX(_Out_ X*)
    

    Wie du siehst, unterscheidet sich die Signatur der beiden Funktionen nicht, d.h. beiden wird ein Zeiger übergeben.

    Ob man nun, x, &x oder *px übergibt, kommt nur darauf an, mit welchen Parametern du die Funktion aufrufst.
    Bei der MSDN-Doku wird halt immer "P..." anstatt "... *" benutzt, da es in der <windows.h> entsprechende 'typedef's für diese Zeigerarten gibt.



  • @Fake oder Echt

    Na siehst du geht doch , jetzt hab ich´s kapiert weshalb das so ist!!!

    Es hat mit OUTPUT und INPUT der Parameter zu tun!

    (Sachen, die mir den Lebensunterhalt einbringen).

    Das finde ich vernünftig , machen ja Viele um sich z.B : Lebensmittel zu kaufen oder Ihren Unterhalt zu bestreiten, oder um sich eine Schönheits - OP zu unterziehen!

    Gruß
    F.Krüger



  • @Proletarier Echt oder Fake bist du noch da?

    Hab mal wieder, nach dem ich das mit den OUT/IN - &/* verstanden habe ,ein neues nicht Verstehen verstanden.

    Es geht um die Ausgabe des Kompilers:

    sWlanInterface->InterfaceInfo[i].strInterfaceDescription	0x00e1bfd0 L"Realtek RTL8187 Wireless 802.11b/g 54Mbps USB 2.0 Network Adapter"	wchar_t[256]
    

    Du erkennst hier einen L (WildChar) welcher einen String beinhaltet.

    Diesen möchte ich gerne mittels printf() ausgeben :

    printf("Interface : %s\n",sWlanInterface->InterfaceInfo[i].strInterfaceDescription);
    

    Nun zeigt mir die Konsole das erste Zeichen "R" und der Rest nicht, wieso?
    Die Kompilerausgabe zeigt mir doch auch die korrekte Textlänge!Hier mal der gesamte Code!

    #define WIN32_LEAN_AND_MEAN
    #include <stdio.h>
    #include <stdlib.h>
    #include <Windows.h>
    #include <wlanapi.h>
    
    #pragma comment (lib,"Wlanapi.lib")
    
    HANDLE pWLANh=0; 
    WLAN_INTERFACE_INFO_LIST *sWlanInterface={0};
    
    int main ()
    {  
    	DWORD WLANh=0;
    	DWORD  verionWlanApi=0;
    	WLANh = WlanOpenHandle (1,0,&verionWlanApi,&pWLANh);  
    
    	if(WLANh == ERROR_SUCCESS)
    	{
    		printf("Wlannetzwerk gestartet!\n\n");
    	}else{
    		printf("Wlannetzwerk nicht gestartet!\n");
    		switch (WLANh)
    		{
    		case ERROR_INVALID_PARAMETER:
    			printf("pdwNegotiatedVersion is NULL, phClientHandle is NULL, or pReserved is not NULL.\n\n");
    			system ("PAUSE");
    			return 1;
    		case ERROR_NOT_ENOUGH_MEMORY:
    			printf("Failed to allocate memory to create the client context.\n\n");
    			system ("PAUSE");
    			return 1;
    		case ERROR_REMOTE_SESSION_LIMIT_EXCEEDED:
    			printf("Too many handles have been issued by the server.\n\n");
    			system ("PAUSE");
    			return 1;
    		}
    
    	}
    
    	WLANh = WlanEnumInterfaces (pWLANh,0,&sWlanInterface);
    
    	if(WLANh == ERROR_SUCCESS)
    	{
    		for (int i=0; i <= sWlanInterface->dwIndex; i++)
    		{
    			printf("Interface : %s\n",sWlanInterface->InterfaceInfo[i].strInterfaceDescription);
    		}
    	}else{
    		switch (WLANh)
    		{
    		case ERROR_INVALID_PARAMETER:
    			printf("pdwNegotiatedVersion is NULL, phClientHandle is NULL, or pReserved is not NULL.\n\n");
    			system ("PAUSE");
    			return 1;
    		case ERROR_NOT_ENOUGH_MEMORY:
    			printf("Failed to allocate memory to create the client context.\n\n");
    			system ("PAUSE");
    			return 1;
    		case ERROR_REMOTE_SESSION_LIMIT_EXCEEDED:
    			printf("Too many handles have been issued by the server.\n\n");
    			system ("PAUSE");
    			return 1;
    		}
    
    	}
    
    	system ("PAUSE");
    	return 0;
    }
    


  • Kompiler habe ich auf "Multibyte" gestellt um t-chars wie chars zu behandeln!



  • Wie Dir die Dokumentation sagt, ist Dein String ein WCHAR - String. Den kannst Du nicht mit printf ausgeben.



  • @Belli,

    völlig falsch!!!

    "Multibyte-Zeichensatz verwenden"

    Behandelt wchars wie chars!!



  • Nein. Behandelt TCHAR wie char ... WCHAR ist immer wchar_t ... wie Dir Dein Programm ja auch zeigt.

    TCHAR ist ein generischer Typ und wird je nach Einstellung (UNICODE oder Multibyte) im Programm via Makrozauberei zu wchar_t oder char.
    Aber ... WCHAR ist nicht generisch und ist immer wchar_t.



  • Absolut Hirnrissig!

    Multibyte behandelt alle UNICODES als ASCII Zeichen !Hör mal ich programmiere schön länger privat und hab soweit alles drauf was man für die Windowsprogrammierung braucht. Gut das mit den Referenzen und Zeiger war mir aufrgrund der schlechten Dokumentation nicht ganz schlüssig!

    Aber eines ist sicher, ein printf() kann ein wchar ,wenn der Kompiler auf Multibyte steht ,interpretieren!

    Das ging die ganze Zeit so!!!



  • Okay ...



  • Belli schrieb:

    Wie Dir die Dokumentation sagt, ist Dein String ein WCHAR - String. Den kannst Du nicht mit printf ausgeben.

    Freddy Kruger schrieb:

    !Hör mal ich programmiere schön länger privat und hab soweit alles drauf was man für die Windowsprogrammierung braucht ...

    Aber eines ist sicher, ein printf() kann ein wchar ,wenn der Kompiler auf Multibyte steht ,interpretieren!

    Lernresistent? Anscheinend geht es ja nicht, oder?

    PS: jedenfalls nicht mit %s im Formatstring.

    - osdt



  • Es ist auch nicht IN/OUTPUT Abhängig.

    Aber Ihr sokratischen Kinder mit instinktverlogenen Eltern haltet euch immer noch mit eure Dialektik für einzigartig, häßliche Hammpelmänner die andere Familien um Ihrer Rasse besteheln nur weil Ihr Krüppel einen schwachsinnigen esoterischen Glauben verfallen seid, Ihr wärt es, weil Ihr gerade als Ratte in diversen Bundeseinrichtungen verteilt sitzt.

    Aber seid beruhigt, Ihr seid´s definitiv nicht und das merken eure "Individuen" , aber was tut man nicht alles für die Scheinheiligkeit und einen dümmlichen Glauben ,das Wohlträchtige genetisch zu bestehlen um anschließend zu ermorden ,damit das Minderwertige dann sagen kann, wir sind´s.Aber errechnet man wieviel positive Genetik ihr schon bestohlen habt und wieviel Missgeburten mit geistiger Minderbemitteltheit Ihr trotzdem leidet, ist die russische Medizin die Beste.

    In diesem Sinne, gegen instinktverlogene faschistische feige Homosexuelle und Lesben die in den Bundeseinrichtungen sitzen,die Vektortechnik und Nanotechnik nutzen um Bürger zu tyrannisieren !

    Kommen wir nun zum eigentlichen Thema!

    DWORD WINAPI WlanGetAvailableNetworkList(
      _In_        HANDLE hClientHandle,
      _In_        const GUID *pInterfaceGuid,
      _In_        DWORD dwFlags,
      _Reserved_  PVOID pReserved,
      _Out_       PWLAN_AVAILABLE_NETWORK_LIST *ppAvailableNetworkList
    );
    

    Es Kommt nicht auf das IN/OUT der Parameter an ,wonach man Referenzen nutzt ,sondern ob die Funktion die Adresse des Pointers braucht oder nicht!

    dwResult = WlanGetAvailableNetworkList(hClient,
                                                 &pIfInfo->InterfaceGuid,
                                                 0, 
                                                 NULL, 
                                                 &pBssList);
    
                if (dwResult != ERROR_SUCCESS) {
                    wprintf(L"WlanGetAvailableNetworkList failed with error: %u\n",
                            dwResult);
                    dwRetVal = 1;
                    // You can use FormatMessage to find out why the function failed
                }
    

    Ansonsten weitere Erklärungen bitte !



  • Kann diesen Mist da oben mal jmd. wegputzen?

    @Freddy Kruger
    Du hast keine Ahnung wovon du schreibst.

    WCHAR ist immer "wide", unabhängig von irgendwelchen Einstellungen.
    Und klar kann man mit printf immer WCHAR Strings ausgeben. Nur eben nicht mit %s . Falls du wissen möchtest wie es geht versuchs mal mit höflich fragen statt dumm und proletenhaft rumpöbeln.



  • hustbaer schrieb:

    Und klar kann man mit printf immer WCHAR Strings ausgeben.

    Jep, da lag ich falsch. Allerdings ist dies wegen des entstandenen Niveaus mein letzter Beitrag in diesem Thread.



  • Freddy Kruger schrieb:

    Absolut Hirnrissig!

    Multibyte behandelt alle UNICODES als ASCII Zeichen !Hör mal ich programmiere schön länger privat und hab soweit alles drauf was man für die Windowsprogrammierung braucht. Gut das mit den Referenzen und Zeiger war mir aufrgrund der schlechten Dokumentation nicht ganz schlüssig!

    Aber eines ist sicher, ein printf() kann ein wchar ,wenn der Kompiler auf Multibyte steht ,interpretieren!

    Das ging die ganze Zeit so!!!

    du hast alles drauf was man für die windows programmierung braucht? *LOL*
    du hast C überhaupt nicht kapiert, das ist dein Problem.
    Bevor du nicht weißt, wie man C programmiert, brauchst du dich um Windows/Linux/... überhaupt nicht kümmern.

    Könntest du C, so hättest du dir kurz im Debugger den String angesehen. Ein wchar_t* String L"abc" sieht im Speicher so aus: 'a' '\0' 'b' '\0' 'c' '\0' '\0' '\0'

    Du machst nun folgendes:
    printf("%s", wideString);
    printf gibt byteweise den char* String aus, bis es auf das erste 0 Byte stößt.
    Nun rate mal warum bei dir nur das erste Zeichen ausgegeben wird...

    Ich empfehle dir, dich intensiv mit C auseinander zu setzen.
    Du hast große Schwierigkeiten mit den Basics, daher klappt das auch nicht mit der Windows Programmierung.
    Im Übrigen würde ich dir empfehlen, am Umgangston zu arbeiten.


Anmelden zum Antworten