eclipse CDT Program kompiliert nicht



  • Hey,

    bin relativ neu in c++. Hab nun ein Programm mit dem miniGW Kompilier für Windows in Eclipse CDT geschrieben, dass mir einfach nur eine Liste der Momentan offenen Prozesse anzeigt. Leider wird das Program nicht kompiliert und es gibt keine Ausgabe. Allerdings kann ich es ohne Fehlerausgabe bauen.

    #include <windows.h>
    #include <tlhelp32.h>
    #include <stdio.h>
    #include <iostream>
    
    int main(int argc, char* argv[]) {
    
    	std::cout << "Hallo";
    
    	HANDLE hSnapShot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0);
    
    	PROCESSENTRY32* processInfo = new PROCESSENTRY32;
    	processInfo->dwSize = sizeof(PROCESSENTRY32);
    
    	while (Process32Next(hSnapShot, processInfo) != FALSE) {
    
    		std::cout<<processInfo->dwSize;
    	}
    
    	CloseHandle(hSnapShot);
    
    	delete processInfo;
    
    	return 0;
    }
    

    Wisst ihr an was das liegen könnte?



  • In den oben dargstellten Quellcode ist natürlich etwas falsch wenn ich die Prozesse ausgeben lassen will muss ich schreiben:

    printf ( "Prozess: %s.\n",processInfo->szExeFile);
    

    Leider wird jedoch in der Konsole gar nichts ausgegeben.


  • Mod

    c_plus_plus_Fragen schrieb:

    Leider wird das Program nicht kompiliert und es gibt keine Ausgabe. Allerdings kann ich es ohne Fehlerausgabe bauen.

    Das ist ein Widerspruch in sich. Bitte beschreibe dein Problem nicht mit Fachwörtern, die du nicht verstehst. Weiche zur Not auf eine einfachere Beschreibung aus. Was tust du? Was erwartest du? Was passiert stattdessen? Bitte jeweils genau beschreiben!

    P.S.: Das new in deinem Programm sieht nach Unfug aus. Das soll sicher ein Objekt mit automatischer Lebensdauer sein. Dies ist sicher nicht der technische Fehler, aber es ist ein schwerer Designfehler.



  • Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C++ (auch C++0x und C++11) in das Forum WinAPI verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • c_plus_plus_Fragen schrieb:

    Leider wird das Program nicht kompiliert und es gibt keine Ausgabe. Allerdings kann ich es ohne Fehlerausgabe bauen.

    Das widerspricht sich aber. Wenn du es bauen kannst, hast du es auch kompiliert. Du meinst wohl eher, dass es nicht ausgefuehrt wird.

    Folgender Code funktioniert unter VS 2013 Preview, wobei es sein kann, dass Eclipse das WinAPI nicht richtig unterstuetzt:

    #include <Windows.h>
    #include <TlHelp32.h>
    //#include <stdio.h>		//Wenn ueberhaupt, dann cstdio. Aber du brauchst printf hier gar nicht
    #include <iostream>
    
    int main()
    {
    	std::cout << "Hallo\n";
    
    	HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); //Koennte man jetz RAII-wrappen, mach ich aber mal nicht
    
    	PROCESSENTRY32 procEntry; //Warum auf dem Heap?
    	procEntry.dwSize = sizeof(PROCESSENTRY32);
    
    	if (Process32First(snapshot, &procEntry)) //Das hat wohl gefehlt
    	{
    		while (Process32Next(snapshot, &procEntry))
    		{
    			std::wcout << procEntry.szExeFile << '\n'; //wcout, weil Visual Studio standardmaessig die W-Varianten der Funktionen nimmt.
    													   //Kann unter Eclipse anders sein. Wenns einen Fehler gibt, probier std::cout<<
    		}
    	}
    	else
    	{
    		std::cout << "Fehler beim Aufruf von Process32First!\n";
    	}
    
    	CloseHandle(snapshot);
    }
    


  • Danke an alle.

    Was ist den schlimm daran wenn das Objekt auf dem Heap statt dem Stack erstellt wird?

    Naja da war es wohl gestern abend etwas spät. Ich meinte der Source wird Fehlerfrei kompiliert und erstellt auch eine entsprechende Binary. Wenn ich diese Binary nun ausführe gibt er mir gar nichts auf der Konsole aus. Keine Fehlermeldung nichts.
    Der Build endet mit der Meldung:

    14:52:03 **** Incremental Build of configuration Release for project TestProcess ****
    Info: Internal Builder is used for build
    g++ -O3 -Wall -c -fmessage-length=0 -o "src\\TestProcess.o" "..\\src\\TestProcess.cpp"
    g++ -o TestProcess.exe "src\\TestProcess.o"

    14:52:04 Build Finished (took 559ms)

    So hab jetzt spaßeshalber mal Code Blocks genommen und siehe da, beide Varianten funktionieren (meine und Jonas). Anscheinend ist eclipse c++ leider noch nicht ausgereift. Auserdem hab ich versucht das Projekt in eclipse in ein neues Projekt auszulagern und zeigt er mir nun jede Menge Fehlermeldungen an, wenn ich versuche zu builden:

    Function CreateToolhelp32Snapshot() could not be resolved

    Function Process32First() could not be resolved

    Sehr merkwürdig. Anscheinend kommt er mit der Windows API nicht wirklich zurecht.

    Eine weitere Frage wäre:
    Wie richte ich den Code Blocks richtig ein?
    Das er mir z.B die {, " und ( automatisch schließt bzw auto imports etc?

    Gibt es da Möglichkeiten?



  • Gleich im Vorfeld mal Sorry fuer ggf. vorhandene Rechtschreibfehler, aber auf nem Kindle tippt sichs nicht so gut.
    Zunaecht mal Heap vs. Stack: Was spricht dagegen, die Variable auf den Stack u legen? Der Heap hat fast nur Nachteile, besonders wenn man ihn so benutzt wie du. Also naked new/delete, denn dann kanns an vielen Stellen leaken. Wenn du zwisxhendrin irgendwas aufrufst, das wirft beispielsweise. In deinem Fall waere das nicht so schlimm, denn ausserhalb der main wirst du eh nx mehr retten koennen. Wenn du dir das aber jetzt ngewoehnst, machst u es auch wonders so. Und frueher oder spaeter wird das leaken. Deswegen: Lege Variblen immer auf dem Stack an, ausser es spricht was gutes dagegen. Und selbst dann solltest du nur RAII-Wrapper benutzen, sprich unique/shared_ptr oder vector (bzw. einen anderen Container, je nach Anwendungsfall).
    Dass dein Code aufeinml geht wundert mich, aber alles ist moeglich. Fuer das WinAPI sollte man dennochVs verwenden. Eclipse hat ja schoen gezeigt, dass diese Non-MS WinAPI-Implemwntierungen nich soo pricklnd sind.
    Bzgl. deiner Kammern kann ich nicht helfen, bei mir macht das Visual Assist X, wobi VS 2012 das glaub ch auch alline macht.

    P.S.: In meinn Code muss mal noch eie Ausgabe vor dem while, da ich immer den ersten Prozess unterschlage 😉



  • Okay danke. Weiß zwar nicht genau was du mit leaken meinst aber okay.

    Ich hab die Methode nochmal etwas angepasst, vielleicht ist es so besser:
    (Ich habe kein Return wert das Process Objekt wird per Pointer übergeben und befüllt, finde es keine schöne lösung da ich 2 mal die selbe If abfrage brauch, allerdings verstehe das ProcessFirst nicht so ganz, gibt es irgendwo eine beschreibung der windows API die ich einbinden kann??

    void getProcess(string &process, PROCESSENTRY32 *procEntry) {
    	HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    
    	procEntry->dwSize = sizeof(PROCESSENTRY32);
    
    	if (Process32First(snapshot, procEntry)) {
    		if (strcmp(procEntry->szExeFile, process.c_str()) == 0) {
    			CloseHandle(snapshot);
    			return;
    		}
    		while (Process32Next(snapshot, procEntry)) {
    
    			if (strcmp(procEntry->szExeFile, process.c_str()) == 0) {
    				CloseHandle(snapshot);
    				return;
    			}
    		}
    	} else {
    		std::cout << "Fehler beim Aufruf von Process32First!\n";
    	}
    
    	CloseHandle(snapshot);
    	procEntry = NULL;
    
    }
    

    Hab nach einigem googln das Problem bzw. die Probleme behoben, war nicht ganz so einfach und hat mich einiges an Zeit gekostet:

    Zum Fehler: Could not be resolved:
    Einfach Projekt Rechtsklick auswählen:
    Properties->C/C++ Build->Settings->Unter dem tab MinGw Linker->Miscellaneous dem Linker Flag den Parameter -windowsm mitgeben.
    Dann:
    Index->Rebuild,Refresh, Resolve unresolved Includes

    Zum Thema mit keinem Consolen output:
    Rechts auf Projekt properties:
    Run/Debug Settings->Auf de generierte .exe eurer Wahl edit-> Environment->New
    Name: PATH
    Value: Path zu eurer MinGW Bin meistens C:/MinGW/bin



  • Leaken bedeutet einfach, Speichrr fuer ein Objekt mit new (oder mehrere mit new[]) zu allokieren und niht wieder freizugeben.
    Du wirst vielleicht sgen "Ich geb schon Alles wieder frei", aber glaub mir, wenn du in spaetern Projekten Funktionen mit x versxhiedenn Ausgaengen hast und noch Exceptions dazu kommen, dann geht das nicht mehr so einfah. Fuern Quellcode bin ich mir gerade zu Schade, ist schonbloed genug, die kommas zu erreichen. Kann ich gerne Morgen machn, wenn ch wiedr zu Hause bin..
    Ich bin gerade ohne Tabs zu faul die PROCESSENTRY32-Struktur anzugucken, vermutlich Funktioniert das aber wie ne einfach verkettete Liste. Process32First ergibt den Anker nd die Next-Funktionen hangeln sih dann die Liste entlang. Ohne Gewaehr vermutlih iists aber so aehnlich.
    Zum nachlesen vonWinAPI- Funnktionen allgemein ist die MSDN dein Freund.



  • Bei der Funktion, mussbes da ein Pointer sin? Koennte mn auh auf return umbauen. Und die 2 ifs durch die etwas cerpoehnte do-while-Scleife umgehen. Das strcmp brauchst du eig. nicht, der ==-Operator von string kann dsas. So erstmal den Urlaub genissen :p



  • Sorry meine Verwirrtheit ich komm aus der Java ecke. Klar das mit der do while hab ich gestern noch gemacht wollte den doppelt Post vermeiden. Nun hab ich noch eine letzte Frage bezüglich den verschieden Styles die man haben kann wenn man so etwas wie eine getProcess Methode verwendet. Ich werde mal kurz die mir ersichtlichen Varianten erläutern. Vielleicht kannst du/ ihr sagen was so das Opti ist:

    1 call by value (stark vereinfacht):

    Process getProcess(string &processString){
    Process process;
    //search Process
    
    return process
    }
    

    call by pointer(?):

    void getProcess(string &processString, Process *process){
    
    //search Process
    fill process; 
    return;
    }
    

    call by value (changed):

    Process &getProcess(string &processString, Process process){
    //search Process
    fill process; 
    
    return &process
    }
    

    call by reference:

    void getProcess(string &processString, Process &process){
    //search Process
    fill &process;
    return;
    }
    

    Wobei bei der letzten varrianter die Frage wäre, wie weiß der compiler was eine Referenz und was ein pointer ist? Eine Referenz ist ja eigentlich ein fester Verweis auf ein beliebiges Objekt im Speicher?

    Wenn nun eine Methode z.B ein pointer auf String fordert, ich aber nur eine Referenz auf das Objekt das den string beinhaltet habe funktioniert so etwas:

    Process &process;
    
    //searchInString requires a pointer of a string
    searchInString(&process.getProcessName());
    

    Auf jedenfall Danke für deine Mühe licht ins Dunkeln zu bringen!



  • Ein Opti gibt es nicht. Jede Moeglichkeit hat Vor- und Nachteile. Du bringst da aber auch was bei den Begrifflichkeiten durcheinander.
    Call by value und Call by reference werden nur fuer uebergebene Parameter verwendet:

    void foo(std::string bar); //Call by value
    void foo(std::string& bar); //Call by reference
    void foo(const std::string& bar); //Call by const reference
    void foo(std::string* bar); //Auch call by reference, aber mit Pointer (wird idR beides so bezeichnet)
    

    Von den 4 Methoden Parameter zu uebergeben nutze ich in der Regel nur die erste oder die dritte: Alle intrinistischen Datentypen (sprich int, char, double,...) uebergebe ich generell by value. Bei denen ist das kopieren teilweise schneller, als Referenzen hin- und herzuschieben. Bei allem anderen, was user-defined ist oder wo sehr viel kopiert werden muesste (std::string, std::vector) uebergebe ich per const reference. Fuer den Aufrufer fuehlt sich das wie ein Call-by-Value-Aufruf an. Man kann, im Gegensatz zu der zweiten Methode auch konstante und temporaere Objekte uebergeben. Im Prinzip ist da der einzige Sinn der Referenz, die Kopie zu sparen. Will ich dagegen das uebergebene Argument veraendern, warum auch immer, nutze ich die zweite Variante. Referenz.member schreiben zu koennen finde ich immernoch angenehmer als Pointer->member. Die letzte Variante ist nur dem Spezialfall vorbehalten, dass ich das zu veraendernde Argument optional machen moechte (der Caller kann nullptr/NULL uebergeben, wenn ers nicht braucht), wobei das seltener vorkommt.
    So viel zu den Argumenten.

    In deinem Fall wuerde ich die Funktion per Return-Value aufbauen. Wenn du was zurueckgeben willst, dann gib auch zurueck, und mach nicht irgendwelches Pointer/Referenz-Gefrickel. Ein guter Compiler wird dann noch RVO durchfuehren; selbst wenn er das nicht tut, bietet seit C++11 die Move-Semantik da noch Optimierungspotential (auch wenn bei einer POD-Struktur wie PROCESSENTRY32 die Kopie schnell genug sein wird, selbst ohne RVO).

    PROCESSENTRY32 getProcess(const std::string& name) //Fuer const T& s.o.
    {
        //Prozess raussuchen
        if(!processFound)
            throw std::runtime_error("Process not found!"); //Oder von mir aus eine Home-Brew-Exception-Klasse
    
        return process;
    }
    

    Die anderen von dir gezeigten Wege wuerde ich nur in Ausnahme-Faellen verwenden. Wenn ich z.B. Exceptions deaktiviert habe o.ae. wuerde ich

    bool getProcess(const std::string& name, PROCESSENTRY32& process) //ggf. mit noexcept
    {
        //Prozess suchen und bei Fund nach process kopieren
    
        return processFound;
    }
    

    nehmen. Oder halt irgend einen Error-Code, wenns schief laeuft. Solche Sachen umgeht man aber am Besten. Solange man nicht einen sehr sehr guten Grund hat, Exceptions zu deaktiveren, sollte man es auch nicht tun.

    Noch ein Wort dazu, warum das WinAPI das oft so macht, beispielsweise eben bei Process32First/Next: Das WinAPI ist kein C++. Es ist ein C-Interface, und da hast du halt weder Referenzen noch Exceptions. Zusaetzlich war es in den fruehen C-Varianten auch noch nicht moeglich, ein struct zurueck zu geben. Da musste man dann eben Argument-Pointer hin- und her schubsen und Fehler durch den Return-Wert angeben.

    EDIT: Bei deinem Pointer-Problem: Du kannst genauso gut &Referenz wie &Variable schreiben. Es kommt dasselbe raus.



  • Okay danke hat mir erstmal sehr geholfen! (hab mich mal registriert werden bestimmt im laufe der Zeit noch mehr Fragen haben 😃 )


Log in to reply