Windows API/Compiler/MSDN Doku, Zeiger - Refernezen



  • Freddy Kruger schrieb:

    Für mich ist jedenfalls DWORD *PDWORD nicht DWORD var = &var.

    Hilft Dir dfas weiter?

    HANDLE WLANh;//Mein Speicher, hier soll Win reinschreiben. 
    PHANDLE pWLANh=&WLANh;//Mein Zeiger zeigt dahin. 
    
    DWORD verionWlanApi;//dito
    PDWORD pVerionWlanApi=&verionWlanApi;//dito
    WlanOpenHandle (1,0,pVerionWlanApi,pWLANh);
    


  • Freddy Kruger schrieb:

    Falsch! Ich übergebe der Funktion die Variable die in der MSDN und Syntax vorgeschrieben wird. Das Typdef PDWORD!

    Das P bei PDWORD steht für Pointer. Eine Funktion erstellt sich Kopien der übergebenen Argumente. Wenn da jetzt also steht PDWORD bedeutet das, das die Funktion gerne einen Pointer auf ein DWORD Wert anlegen möchte. Also musst du ihm eine Adresse übergeben und keinen Pointer auf gar nichts.

    Freddy Kruger schrieb:

    Und der Kompiler akzeptiert das auch!

    DWORD WLANh=0;
    PHANDLE pWLANh=0; 
     
    PDWORD  verionWlanApi=0;
    WlanOpenHandle (1,0,verionWlanApi,pWLANh);
    

    Klar akzeptiert er das, er geht davon aus, dass verionWlanApi auf einen gültigen Speicherbereich zeigt. Dass du den Pointer nicht richtig initialisiert hast, ist nicht wirklich des Compilers Problem. Sieh es als Freiheit an, so einen Schwachsinn verzapfen zu dürfen.

    Freddy Kruger schrieb:

    Wenn ich jetzt noch referenzieren würde...

    DWORD WLANh=0;
    PHANDLE pWLANh=0; 
     
    PDWORD  verionWlanApi=0;
    WlanOpenHandle (1,0,&verionWlanApi,&pWLANh);
    

    Die Begrifflichkeiten scheinst du ja zu beherrschen. Den Rest aber noch nicht. Beschäftige dich nochmal mit Zeigern, dann verstehst auch du, warum das Schwachsinn ist.

    Freddy Kruger schrieb:

    Dann bekomme ich Syntaxfahler!

    Was für eine Schweinerei! Böser Compiler!

    Freddy Kruger schrieb:

    Wenn ich die Variablen direkt referneziere , indirekter Pointer, nicht wie in der MSDN steht. Dann funktioniert die Funktion auch nach dem kompilieren!

    WORD WLANh=0;
    HANDLE pWLANh=0; 
     
    DWORD  verionWlanApi=0;
    WlanOpenHandle (1,0,&verionWlanApi,&pWLANh);
    

    Oben bereits erklärt. Das ist gemäß MSDN und zumindest meiner schmalen Kenntnis der Programmiersprache C endlich mal ein Stück valider Code (oder hieß es Kot?).

    Freddy Kruger schrieb:

    Für mich ist jedenfalls DWORD *PDWORD nicht DWORD var = &var. Die Logik würde ich dann gerne erklärt bekommen, da es auch Funktionen gibt die auch das wollen was angegeben ist z.B HANDLE *PHANDLE = PHANDLE pHandle als Parameter (pHandle) ohne (&)!

    An was kann man jetzt die Bedürfnisse der Funktion erkennen, ob & oder *??

    Hier erkenne ich auf jeden Fall etwas, was dein Bedürnis sein sollte: Pointer und Bedeutung der Typen. Alle weiteren "Bedürfnisse" stehen in der Beschreibung. Man muss nur fähig sein, diese entsprechend rauslesen zu können. Dafür reichen aber grundlegende Kenntnisse der Programmiersprache C sowie der Weltsprache Englisch.

    EDIT: volkard war schneller ^^



  • Ok , und was sagt uns diese SDK , das ich Schwachsinn schreibe??

    http://www.manpagez.com/man/3/pcap_freealldevs/

    Hier wird die Syntax genau so angegeben wie bei MSDN Funktionen, nur ohne Typdef, was egal ist.

    SYNOPSIS
           #include <pcap/pcap.h>
    
           void pcap_freealldevs(pcap_if_t *alldevs);
    

    Die Funktion will :

    pcap_if_t *TPCAP;
    pcap_freealldevs(TPCAP); //Wo zeige ich denn bitte auf nichts??? Es geht darum das der Wert manipulierbar bleibt und kein Speicherzugriffsfehler passiert!
    


  • @Fake oder Echt

    Und jetzt bist ruhig oder was? In der MSDN steht nix von & oder * , weder in English noch in der eigentlichen Geistersprache DOITSCH ^^

    GEHT NICHT!!!

    DWORD WINAPI WlanOpenHandle(
      _In_        DWORD dwClientVersion,
      _Reserved_  PVOID pReserved,
      _Out_       PDWORD pdwNegotiatedVersion, // Nur Typdef ,Variable mit Zeiger
      _Out_       PHANDLE phClientHandle       // Nur Typdef ,Variable mit Zeiger
     );
    
    DWORD WLANh=0;
    PHANDLE pWLANh=0; 
    
    PDWORD  verionWlanApi=0;
    WlanOpenHandle (1,0,verionWlanApi,pWLANh);
    

    GEHT !!!

    #include <pcap/pcap.h>
    
           void pcap_freealldevs(pcap_if_t *alldevs);
    
    pcap_if_t *TPCAP;
    pcap_freealldevs(TPCAP);
    

    Vielleicht bin ich nicht Kantig genug um´s zu verstehen oder zu verbogen um vernünftig zu sein, vielleicht fehlen mir auch einfach die Fleischwunden im Gesicht um´s zu verstehen ,vielleicht sollte ich auch mal langsam eine Familie gründen mit schönen Kindern und als selbsternannter Über diese als Über definieren. Aber bitte, mach mich schlau ^^



  • Freddy Kruger schrieb:

    @Fake oder Echt

    Und jetzt bist ruhig oder was? In der MSDN steht nix von & oder * , weder in English noch in der eigentlichen Geistersprache DOITSCH ^^

    Erstmal bin ich berufstätig, das bedeutet, dass ich meine Zeit größtenteils für wichtigere Sachen nutze (Sachen, die mir den Lebensunterhalt einbringen). Wenn ich dann in einer kurzen Pause meine Zeit jemanden wie dir opfere, fällt mir gleich wieder ein, warum ich hier eigentlich nur noch lese und nicht schreibe.
    In der MSDN steht sehr wohl beschrieben, ob ein Array, ein Pointer, ein simpler Wert oder was auch immer an die Funktion übergeben werden soll. Das zu interpretieren erfordert nicht, ein (Denk-)Sklave Microsofts zu werden, sondern nur sich in Sachverhalte einzuarbeiten und diese auch verstehen zu können.
    Warum die von dir so hart ersehnten De-/Referenzierungssymbole nicht in der MSDN direkt stehen, wirst du nicht verstehen wollen, deshalb belasse ich es dabei. Verschwörungstheoretiker behaupten aber, dass Microsoft dies in seiner geheimen Unnutzbarkeitskampagne bewusst so beschrieben hat, um - wie der Name der Kampagne es vermuten lässt - möglichst viele Schwierigkeiten und Komplikationen einzubauen und so die Nutzbarkeit massiv zu reduzieren und Nicht-MS-Programmierer (quasi die Uneingeweihten) damit in den Wahnsinn und in die Verzweiflung zu treiben.

    Freddy Kruger schrieb:

    pcap_if_t *TPCAP;
    pcap_freealldevs(TPCAP); //Wo zeige ich denn bitte auf nichts??? Es geht darum das der Wert manipulierbar bleibt und kein Speicherzugriffsfehler passiert!
    GEHT NICHT!!!
    

    In diesem Fall zeigst du auf einen Pointer, der auf nichts zeigt. Du übergibst um ganz genau zu sein eine Adresse, in der nichts ist. Somit ließe sich als Zirkelschluß formulieren, dass du auf nichts zeigst. Die Funktion muss damit arbeiten können, dann geht das auch.

    DWORD WINAPI WlanOpenHandle(
      _In_        DWORD dwClientVersion,
      _Reserved_  PVOID pReserved,
      _Out_       PDWORD pdwNegotiatedVersion, // Nur Typdef ,Variable mit Zeiger
      _Out_       PHANDLE phClientHandle       // Nur Typdef ,Variable mit Zeiger
     );
    
    DWORD WLANh=0;
    PHANDLE pWLANh=0; 
    
    PDWORD  verionWlanApi=0;
    WlanOpenHandle (1,0,verionWlanApi,pWLANh);
    

    [/quote]
    Hier sagst du "Liebes, liebes Windows. Bitte initialisiere mir verionWlanApi doch bitte so, dass es vorerst auf keine Adresse zeigt. Danach übergebe bitte die Adresse an WlanOpenHandle."
    Windows sagt "Klar, gerne. Ich rufe dann auch gleich mal WlanOpenHandle auf."
    WlanOpenHandle schaltet sich ein und sagt "Ich wollte doch in den Inhalt einer Adresse schreiben, habe aber keine für mich Gültige bekommen, das mache ich so nicht."

    Auf Grund deiner mangelnden Umgangsformen werde ich dir allerdings nicht weiter antworten, volkard hatte im Übrigen ein eigentlich verständliches Beispiel gepostet.



  • 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.


Anmelden zum Antworten