Speicheradressen



  • Hallo, ich hätte mal eine Frage. Ich bin Umsteiger von C# auf C++. Ich habe mich mal in verschiedene Projekte auf Github reingelesen und habe bemerkt, dass sehr oft mit Pointern bzw. Speicheradressen gearbeitet wird.

    Kann mir wer erklären, wann genau mit Pointern, oder '&' gearbeitet wird ?

    Soweit ich weiß, schreibt man mit dem '&' auf die gleiche Speicheradresse, wie das Objekt, auf welches sich das '&' bezieht, richtig ?

    Z.B. bei aufrufen eines externen Programmes habe ich ein paar Variablen initialisiert.

    STARTUPINFO startupinfo = { 0 };
    PROCESS_INFORMATION pi = { 0 };
    

    Die Funktion CreateProcess() wirft ja einen BOOL zurück.

    Ich habe die meisten Argumente der Funktion auf NULL gesetzt, bis auf halt den PATH bzw. den NAME, außer die PROCESS_INFO und die STARTUPINFO.

    #include <iostream>
    #include <Windows.h>
    
    
    int main(int argc, char** argv[]) {
    	std::string NP_PATH = "C:\\Windows\\notepad.exe";
    	STARTUPINFO startupinfo = { 0 };
    	PROCESS_INFORMATION pi = { 0 };
    	
    	BOOL success = CreateProcess(TEXT("C:\\Windows\\notepad.exe"), NULL, NULL, NULL, FALSE, NULL, NULL, NULL, &startupinfo, &pi);
    	if (!success == 1) {
    		std::cout << "FAIL";
    	}
    	else {
    		std::cout << "SUCCESS";
    	}
    }
    

    Warum wird vor den Variablen startupinfo und pi das '&' angegeben ?

    Es wird ja auf die Speicheradresse durch dessen geschrieben. Aber warum ? Könnte man nicht einfach auf den Wert der Variable zugreifen ?

    Danke im Voraus.



  • Die einfache Antwort hier ist: CreateProcess verlangt nunmal Zeiger. Man sollte auch im Hinterkopf behalten, das CreateProcess aus der WinAPI ist und somit in C. In C gibt es keine Referenzen.



  • @Braunstein Danke, du hast mir weitergeholfen. Gibt es Alternativen zu CreateProcess, wie z.B. ShellExecute / ShellExecuteEx ?


  • Mod

    Das CreateProcess kommt ja von Windows.h, was eine C-Bibliothek ist, daher gibt es keine C++-artige Schnittstelle, außer man schreibt sie selber drumherum (viel Arbeit…). Haben aber zum Glück andere Leute schon getan, zum Beispiel boost.Process. Ist dann in boost-typischer Manier sehr C++-ig, was vielleicht nicht jedes Einsteigers Sache ist, aber du hast ja danach gefragt.



  • @Aleskej
    Eine kleine Anmerkung.

    Du musst bei deiner startupinfo Variable den cb Member setzen.

    startupinfo.cb = sizeof(STARTUPINFO);
    

    Siehe auch:

    MSDN Beispiel



  • @Aleskej sagte in Speicheradressen:

    Könnte man nicht einfach auf den Wert der Variable zugreifen ?

    Ich glaube nicht, dass der TE (explizit) nach Referenzen gefragt hat, oder nach einer C++-artigen Schnittstelle. Ich vermute, hier fehlt noch einiges an Hintergrundwissen.
    @Aleskej : auch in C# wäre es kein "auf den Wert der Variable zugreifen". Wichtig ist erstmal, was die Funktion für Parameter erwartet. In C# gibt es Klassen und Structs, und Structs sind auch erstmal pass by value, d.h., die werden kopiert (und das würde man in C meist vermeiden wollen, weil das Zeit kostet). Wenn die Funktion den Parameter per Referenzen verlangen würde (ref struct x), würde der Compiler an der Stelle einer Referenz auf das Objekt übergeben. Aber die Funktion greift so oder so nicht auf die Variable zu.

    Das war jetzt natürlich eine sehr grobe Beschreibung. In C++ gehört da syntaktisch und semantisch einfach noch ein bisschen mehr dazu, da musst du dich mit der Zeit einlesen.



  • @SeppJ Okay, danke. Verwendet man dies des öfteren, oder verwendet man eher CreateProcess bzw. ShellExecute ?



  • @Mechanics Dankeschön. Ich bin derzeit 14 und habe noch nicht allzugroße Ahnung davon.



  • Das ist unterschiedlich, aber es bietet sich eher an, plattformunabhängig zu programmieren, und da ist boost (oder z.B. auch Qt) besser. CreateProcess/ShellExecute sind Windows Funktionen und deswegen würde man das doch wieder umbauen müssen, falls man das Programm oder Teile davon z.B. unter Linux betreiben möchte.
    Auf der anderen Seite - mit plattformspezifischen Funktionen könnte man vielleicht etwas hinbekommen, was man mit den plattformübergreifenden Abstraktionen nicht hinbekommt. z.B. wüsste ich grad nicht, wie man ShellExecute mit boost process nachbildet - kann aber durchaus sein, dass das geht, hab damit bisher nicht viel gemacht.


  • Mod

    Ich würde eher sagen, dass es allgemein recht unüblich ist, selber neue Prozesse zu spawnen. Die einsatzzwecke sind ja a) Das Starten eines komplett anderen Programms oder b) gewisse Formen der Parallelisierung. a) kommt recht selten vor, dass man solche Bedürfnisse hat außerhalb von Übungsaufgaben, und bei b) nimmt man fertige Frameworks für Parallelisierung. Von daher wäre meine Antwort: Keines von beidem wird viel benutzt. Aber wenn ich irgenwie das Bedürfnis nach intensiver Kommunikation mit einem Subprocess hätte, würde ich boost nehmen. Wenn ich nur irgendwas spawnen wollte, ohne große Intraprocesskommunikation und dies sicher nur auf einer Plattform laufen soll, dann würde ich direkt die Plattformfunktionen dafür nutzen.


Log in to reply