Anfängerfrage: mehrere Mains selektiv aufrufen
-
Hallo Zusammen,
ich habe ein Projekt in MS Visual C++ erstellt, in dem ich nach und nach diverse Dinge ausprobieren und implementiere. Diese kleinen Einheiten die ich durch durchspiele, sind alle für sich abgeschlossen in einer *.c Datei und beinhalten eine int main(..). Da ich nun nicht jedes mal ein neues Projekt anlegen will (da pro Projekt nur eine Main), möchte ich das anders lösen.
Ich möchte eine main.c in der es eine Main Methode gibt. In dieser Main möchte ich dann immer die Einheit einkommentieren, die ich gerade ausführen lassen möchte. Ich würde also in den restlichen *.c Dateien die int main(...) umbenennen in void test1main(...) in test1.c, void test2main(...) in test2.c usw. Das Problem ist nun, wie rufe ich die test1main(...) aus test1.c in Main.c auf? Die gesamten Parameter der main sollen ebenfalls "durchgeschliffen" werden. Für einen Beispiel-Main wäre ich sehr dankbar

-
Du brauchst für jede *.c (warum verwendest du nicht *.cpp?) Datei eine Headerdatei *.h in der du die testmain deklarierst und die bindest du in deine main ein und kannst die dann aufrufen.
-
In unserem Studium haben wir es so gelernt:
main.cpp (*.cpp für c++, *.c ist für c)
#include "test1.h" int main(int argc, char* argv[]) { test1(6,5); }test1.cpp
#include "test1.h" //Hier kommen deine Routinen rein... Bsp.: void test1(int &valueA, int &valueB) { }test1.h (*.h sind Headerdatein)
#ifndef TEST1_H #define TEST1_H void test1(int &valueA, int &valueB); #endifIch hoffe die kleine Hilfe hat dir etwas gebracht. Was die Bezeichner zu bedeuten haben findest du im Internet. Würde es dir gerne noch erklären aber ich muss jetzt los.
mfg frock und viel Spaß bei weiteren rumbasteln

-
Tip: header müssen nicht so heißen wie die .cpp wo die im header deklarierten Funktionen definiert worden sind. Folgendes geht also durchaus:
programm1.cpp
//... #include "collectmains.h" //NEU //int main(int argc, char* argv[]) //AUSKOMMENTIERT int testmain1(int argc, char* argv[]) //NEU { /*...*/ }andere mains ähnlich umgestalten
collectmains.h
int testmain1(int argc, char* argv[]); int testmain2(int argc, char* argv[]); int testmain3(int argc, char* argv[]);maincollector.cpp
#include "collectmains.h" #include <iostream> int main(int argc, char* argv[]) { int i = 0; std::cout << "Programm waehlen (1-3): " << std::flush; std::cin >> i; switch (i) { case 1: return testmain1(argc, argv); case 2: return testmain2(argc, argv); case 3: return testmain3(argc, argv); default: std::cerr << "Falsche Programmwahl!" << std::endl; return -1; } }
-
Man kann auch ruhig Funktionen schreiben, die die gleiche Signatur wie
main()besitzen - bis auf den Namen. Bedingung ist, dass die Hauptfunktionmain()genau einmal vorkommt.
-
Vielen Dank, das ging schonmal super (habe pumuckls Lösung realisiert)

Jetzt habe ich allerdings das Problem:
Bisher hatte ich nur eine testmain1 in test1.cpp, die eine Header-Datei (control.h) inkludiert. Nun habe ich eine testmain2 in test2.cpp, welche ebenfalls diese control.h inkludieren muss.
Das Problem ist nun, wenn ich in der main.cpp zwischen diesen beiden testmain1 und testmain2 umschalte und dann kompiliere/linke kommt:
"test2.obj : error LNK2005: "void __cdecl create_control(void)" (?create_control@@YAXXZ) ist bereits in test2.obj definiert." "fatal error LNK1169: Mindestens ein mehrfach definiertes Symbol gefunden."
Kann mir jemand sagen, wie ich das umgehen?

-
Mork0075 schrieb:
Kann mir jemand sagen, wie ich das umgehen?

Ja. In die Headerdateien kommen nur Deklarationen (Variablen, Funktionen). Deren Definitionen schreibst du in eigene CPP-Dateien, die dann jeweils die entsprechenden Header einbinden.
//------- Blabla.hpp ------- void Func(int x, double& y); extern int GlobalVar; //------- Blabla.cpp ------- #include "Blabla.hpp" void Func(int x, double& y) { y *= x; } int GlobalVar = 7; //------- Main.cpp ------- #include "Blabla.hpp" int main() { double a; Func(GlobalVar, a); }
-
google mal nach Include Guards, die sollten das Problem beheben.
-
Die Include-Guards brauchten leider keine Abhilfe. Die control.h ist eine Art Fernbedienung zur Steuerung von Abläufen, die mir jemand extern gegeben hat. Kann es sein, dass dort Fehler drin sind? Ich versteh ehrlich gesagt nicht, wo das Problem ist.
Ich habe eine main von der aus ich submain1 und submain2 je nach Lust und Laune aufrufen möchte. Die subs stehen in keinerlei Vererbungsbeziehung usw. Wieso kommt es zu Problemen beim Linken?
-
Mork0075 schrieb:
[...] Die control.h ist eine Art Fernbedienung zur Steuerung von Abläufen, die mir jemand extern gegeben hat. Kann es sein, dass dort Fehler drin sind? [...]
No na...

Zeig doch.
cheers, Swordfish
-
Das ist die control.h
#include <LEDA/graphics/window.h> static leda::window *ControlWindowP; static double ControlWindowSpeed; void create_control() { ControlWindowP = new leda::window(260,60,"Remote Control"); //panel_item pi=ControlWindowP->int_item("Speed",ControlWindowSpeed,95,105,1,"Animation Speed"); ControlWindowP->buttons_per_line(3); ControlWindowP->button("Stop",41); ControlWindowP->button("Step",42); ControlWindowP->button("Cont",43); ControlWindowP->button("Slow",44); ControlWindowP->button("Normal",45); ControlWindowP->button("Fast",46); ControlWindowSpeed = 1.0; ControlWindowP->display(0,0); } void destroy_control() { ControlWindowP->close(); delete ControlWindowP; } void control_wait(double t) { int val; double x,y; //while (ControlWindowP->get_event(val,x,y)!=no_event) ; int i; for (i=0; i<20; i++) { val = ControlWindowP->get_mouse(x,y); //if (val!=NO_BUTTON) cout<<"ControlWindowP: " <<val <<endl; switch(val) { case 41: ControlWindowSpeed=0.0; break; case 42: ControlWindowSpeed=-1.0; break; case 43: ControlWindowSpeed=1.0; break; case 44: ControlWindowSpeed=2.0; break; case 45: ControlWindowSpeed=1.0; break; case 46: ControlWindowSpeed=0.3; break; } } if (ControlWindowSpeed==0.0) { while (ControlWindowSpeed==0.0) { val = ControlWindowP->get_mouse(x,y); //if (val!=NO_BUTTON) cout<<"ControlWindowP: " <<val <<endl; switch(val) { case 41: ControlWindowSpeed=0.0; break; case 42: ControlWindowSpeed=-1.0; break; case 43: ControlWindowSpeed=1.0; break; case 44: ControlWindowSpeed=2.0; break; case 45: ControlWindowSpeed=1.0; break; case 46: ControlWindowSpeed=0.3; break; } } } if (ControlWindowSpeed==-1.0) { ControlWindowSpeed=0.0; } else { #if __LEDA__ < 360 wait(t*ControlWindowSpeed); #else leda_wait(t*ControlWindowSpeed); #endif } } #define leda_wait control_waitDiese inkludiere ich sowohl in test1.c als auch in test2.c Über eine Main.c inkl. main(...) will ich nun selektiv (durch Auskommentieren) eine Methode aus test1 oder test2 aufrufen. Sobald sowohl test1 als auch test2 im Projekt sind, kommen beim Linken solche Fehler:
"test2.obj : error LNK2005: "void __cdecl create_control(void)" (?create_control@@YAXXZ) ist bereits in test1.obj definiert." "fatal error LNK1169: Mindestens ein mehrfach definiertes Symbol gefunden."
Die Sache mit den Guards habe ich wie gesagt schon ausprobiert, bringt aber nichts. Wenn ich test1 oder test2 aus dem Projekt raus werfe, dann klappts. Was ja aber gerade nicht der Sinn war

Vielen Dank schonmal
-
Kannst du mir sagen, wieso du meine Posts nicht liest?

Ich habe bereits erklärt, woran das liegt, und auch einen entsprechenden Lösungsvorschlag gebracht.
-
In wie fern habe ich dagegen verstoßen? Die control.h ist fix, die habe ich so bekommen und muss/will sie auch so verwenden. In meiner mains.h stehen in der Tat nur Deklarationen. Also was tun?
-
Entweder Include Guards in die control.h oder, was häßlicher ist, um jedes der includes.
-
Habe jetzt um die gesamte control.h einen Include Guard gemacht, gleiches Problem.
-
Wie sehen deine Include Guards denn aus?
-
Include Guards bringen nichts,
denn zur Compile time ist die control.h ja nur
einmal prro file included.
Allerdings steht da jeweil in jeder testX.obj die definition der Funktionen darin.
Die lösung heist also: Aufsplitten in Header und Implementation//! control.h #include <LEDA/graphics/window.h> extern static leda::window *ControlWindowP; extern static double ControlWindowSpeed; void create_control(); void destroy_control(); ...//! control.cpp #include "control.h" void create_control() { ControlWindowP = new leda::window(260,60,"Remote Control"); //panel_item pi=ControlWindowP->int_item("Speed",ControlWindowSpeed,95,105,1,"Animation Speed"); ControlWindowP->buttons_per_line(3); ControlWindowP->button("Stop",41); ControlWindowP->button("Step",42); ControlWindowP->button("Cont",43); ControlWindowP->button("Slow",44); ControlWindowP->button("Normal",45); ControlWindowP->button("Fast",46); ControlWindowSpeed = 1.0; ControlWindowP->display(0,0); } void destroy_control() { ControlWindowP->close(); delete ControlWindowP; } ...mfg branleb
-
Danke, habs jetzt mal so umgebaut. Bei Zeile 4 und 5 deiner control.h sagt er "error C2159: Mehr als eine Speicherklasse angegeben"
-
Extern sagt aus, dass das Element in einer anderen Übersetzungseinheit (Sourcefile) definiert wird. Static besagt, dass das Element nur in dieser einen ÜE gültig ist. Das beisst sich natürlich ein wenig.
Also musst Du die beiden Variablen entweder nur static nur in control.cpp notieren, oder aber extern in der control.h und ohne Speicherklasse nochmal in control.cpp.
-
sorry, das hab ich übersehen ...
Da das Globale Variablen sind, sehe ich für static auch wenig sinn.
Daher würde ich dir extern empfehlen.mfg branleb