C++ Code in Visual c++



  • Wenn ich das mache:

    LPCWSTR username=(const wchar_t*)(Marshal::StringToHGlobalUni(networkList[3])).ToPointer();

    Und später das:

    Marshal::FreeHGlobal(System::IntPtr(username));

    Dann bekomme ich folgende Meldung:

    error C2440: '<function-style-cast>': 'LPCWSTR' kann nicht in 'System::IntPtr' konvertiert werden

    Was ist mit der Struktur
    NETRESOURE

    Muss der Speicher hierfür freigegeben werden?



  • Marshal::FreeHGlobal((System::IntPtr)username);
    

    und hast Du "nr" _allokiert_?



  • Hallo Jochen,

    leider bin ich in c oder c++ nicht so gewandt, was den Ausdruck allocate anbelangt.

    Ich nehme mal an, Du meist damit das Anlegen eines Zeigers für die Adresse.
    Nein, dass habe ich nicht getan, einfach nur:

    NETRESOURCE nr;

    Der Aufruf erfolgt in einer Funktion; wird der Speicher dann wieder automatisch freigegeben, wie es in VC2008 üblich ist?

    Ich habe, wie in Deiner Antwort, außerdem die Klammern im folgenden Code Abschnitt geändert:

    Marshal::FreeHGlobal((System::IntPtr)username);

    Die Fehlermeldung bleibt aber fast gleich:

    error C2440: 'Typumwandlung': 'LPCWSTR' kann nicht in 'System::IntPtr' konvertiert werden

    Danke für die Hilfe!



  • Hallo Jochen,

    kannst Du mir hier bitte nochmal aushelfen?





  • Guten Morgen Jochen,

    ich habe mal versucht, den Code mit den includes anzuwenden.

    NETRESOURCE nr;
    	nr.dwType = RESOURCETYPE_ANY;
    	nr.lpProvider = NULL;
    
    	msclr::interop::marshal_context c1;
    	wchar_t *lpRemote = c1.marshal_as<wchar_t*>(networkList[1]);
    	msclr::interop::marshal_context c2;
    	wchar_t *lpName = c2.marshal_as<wchar_t*>(networkList[2]);
    
    	nr.lpRemoteName=lpRemote;
    	nr.lpLocalName=lpName;
    
    	msclr::interop::marshal_context c3;
    	const wchar_t *username = c3.marshal_as<const wchar_t*>(networkList[3]);
    	msclr::interop::marshal_context c4;
    	const wchar_t *password = c4.marshal_as<const wchar_t*>(networkList[4]); 
    
    	DWORD net = WNetAddConnection2(&nr,password , username, CONNECT_UPDATE_PROFILE);
    

    Das funktioniert:

    msclr::interop::marshal_context c3;
    	const wchar_t *username = c3.marshal_as<const wchar_t*>(networkList[3]);
    	msclr::interop::marshal_context c4;
    	const wchar_t *password = c4.marshal_as<const wchar_t*>(networkList[4]);
    

    Muss ich hier den Speicher wieder freigeben?

    Das geht nicht:

    msclr::interop::marshal_context c1;
    	wchar_t *lpRemote = c1.marshal_as<wchar_t*>(networkList[1]);
    	msclr::interop::marshal_context c2;
    	wchar_t *lpName = c2.marshal_as<wchar_t*>(networkList[2]);
    

    Ich nehme an, dass das nicht geht, weil marshals_as das nicht kann.

    Wie kann ich das sonst lösen?



  • Hab Dein Code mal mot CodeTags versehen... bitte nächstesmal selber den Code markieren und auf "C/C++" drücken 😉

    Speicher musst Du nicht freigeben... das macht der "marshal_context" für Dich...

    Es sieht so aus, als ob das marshal_as-Zeugs nur const kann...

    Aber WARUM geht Dein ursprüngliches nicht?

    Bei mir geht das Wunderbar:

    String^ s = "hello world";
      wchar_t * sz = static_cast<wchar_t*>(System::Runtime::InteropServices::Marshal::StringToHGlobalUni(s).ToPointer()); 
    
      System::Runtime::InteropServices::Marshal::FreeHGlobal((IntPtr)sz);
    


  • Hallo Jochen.

    Ich hatte das vorher direkt an nr.lpRemoteName und an eine Variable LPCWSTR übergeben.

    nr.lpLocalName= (wchar_t*)(System::Runtime::InteropServices::Marshal::StringToHGlobalUni(networkList[1])).ToPointer();
    

    Das hat auch funktioniert, die Frage war, ob ich hier Speicher freigeben muss?

    LPCWSTR username= (const wchar_t*)(System::Runtime::InteropServices::Marshal::StringToHGlobalUni(networkList[3])).ToPointer();
    

    Für LPCWSTR username ging das z.B. nicht:

    Marshal::FreeHGlobal((System::IntPtr)username);
    

    Auch hier lautet die Frage, ob hier Speicher freigegeben werden muss.

    Ich habe das nun so umgesetzt, wie Du es vorgebenen hast und es funktioniert.
    Danke für die Gedult und die Lehrstunde.



  • Die Regel ist einfach: Wenn Du Speicher allokierst, musst Du ihn wieder freigeben... (also malloc, new, StringToHGlobalUni, ...)



  • Ja, jezt weiß ich auch was Du mit allokiert meinst und wie man das macht.

    Danke nochmals.


Anmelden zum Antworten