Push-Nachrichten von MacTechNews.de
Würden Sie gerne aktuelle Nachrichten aus der Apple-Welt direkt über Push-Nachrichten erhalten?
Forum>Entwickler>C++ Hilfe gesucht

C++ Hilfe gesucht

andreas_g
andreas_g02.01.2410:33
Liebe Community,

ich arbeite seit längerer Zeit an einem Emulator. Auch andere Personen haben Teile dazu beigetragen. Unter Anderem enthält das Programm einen internen NetInfo-Server. Dieser wurde allerdings beigesteuert und in C++ geschrieben. Mein Problem ist nun, dass der Entwickler dieses Codes nicht mehr erreichbar ist und ich selbst über keine C++-Fähigkeiten verfüge.

Kann mir vielleicht jemand helfen, folgende Änderung an der Funktionalität vorzunehmen?

Ich möchte, dass im Falle eine Reset via nfsd_start() () die Datenstruktur sNetInfoBindProg ( und ) entweder anhand der aktuellen Einstellungen neu erstellt oder via configure() () anhand der aktuellen Einstellungen aktualisiert wird.

Es geht dabei in erster Linie darum, den Eintrag ntp abhängig von den Einstellungen einzufügen oder zu entfernen (das habe ist mir in einer vermutlich sehr unsauberen Lösung gelungen) und den string systemType in die betreffenden Einträge zu schreiben beziehungsweise zu aktualisieren (daran scheitere ich leider).

Ich bin für jeden Hinweis dankbar. Leider ist das einzige, das ich anbieten kann, ein Eintrag in die Contributors List (und die damit verbundene immerwährende Ehre ).
0

Kommentare

Mapple
Mapple02.01.2414:16
Hi andreas_g,

also, ich würde mich an Deiner Stelle mithilfe von ChatGPT "durcharbeiten" und sehen, wie weit ich komme...
Stelle klare Fragen zu dem jeweiligen Codeabschnitt und definiere die Aufgabenstellung.
Prüfe den Code und arbeite Dich durch die Fehlermeldungen mit ChatGPT.

Du wirst Dich wundern, wie weit Du kommst
0
AidanTale02.01.2415:08
Dadurch das sNetInfoBindProg eine statische Variable ist wird beim Aufruf von nfsd_start() deren Konstruktor nicht nochmal aufgerufen. Selbst wenn man das ändern würde krankt der ganze Kode daran, dass man irgendwie das Aufräumen vergessen hat.

Systemtype scheint nur hier verwendet zu werden:
machinesadd(NIProps("name","localhost")("ip_address",ip_addr_str(0x7F000001, 4))("serves","./local")("netgroups","")("system_type",systemType));

Du müßtest also entweder eine delHost() Methode für m_Local schreiben so dass du bei Änderungen diese gefolgt von addHost mit aktuellem SystemType aufrufen kannst, oder aber schauen ob es zu dem add da oben ein del/remove gibt mit dem du den Localhost-Eintrag ändern kannst.
+2
andreas_g
andreas_g02.01.2415:34
AidanTale
Danke für die kurze Analyse! Eine bestehende Routine gibt es nicht. Genau daran scheitere ich aber. Meine kläglichen Versuche eine Routine zum Entfernen eines NetInfoNodes zu schreiben sind hier zu sehen: .

Ich müsste in via configure() folgendes rückgängig machen und anschließend neu erstellen:
243: addHost(m_Local, NAME_HOST, systemType);
250: machinesadd(NIProps("name",NAME_HOST)("ip_address",ip_addr_str(CTL_NET|CTL_HOST,  4))("serves",NAME_HOST"/local")("netgroups","")("system_type",systemType));
259: locationsadd(NIProps("name","ntp")("server",NAME_NFSD)("host",NAME_NFSD));

Wie würden solche Routinen aussehen und wie müsste ich sie korrekt aufrufen (inklusive des Auffindens der zu entfernenden Daten)?

P.S. Ich habe leider keine Möglichkeit gefunden, die automatische Ersetzung mit Emojis und Symbolen zu deaktivieren. Leider passiert das sogar bei Text, der als Code markiert ist. ist - gefolgt von > (dereferencing operator).
0
AidanTale02.01.2418:05
In CNetInfoBindProg::configure(bool) sieht man ja wie ein Node gelöscht wird. Das könnte man mit dem LocalNode probieren, also ungefähr so:

/* Remove local machines */
vector<NetInfoNode*> old = m_Local.mRoot.find("name","machines");
m_Network.mRoot.remove(old[0]);

/* Add local machines for new SystemType */
string systemType = ConfigureParams.System.nMachineType == NEXT_STATION ? "NeXTstation" : "NeXTcube";
if(ConfigureParams.System.nMachineType == NEXT_STATION && ConfigureParams.System.bColor)
    systemType += " Color";
NetInfoNode* machines = m_Local.mRoot.add(NIProps("name","machines"));
machinesadd(NIProps("name","broadcasthost")("ip_address",ip_addr_str(0xFFFFFFFF, 4))("serves","../network"));
machinesadd(NIProps("name","localhost")("ip_address",ip_addr_str(0x7F000001, 4))("serves","./local")("netgroups","")("system_type",systemType));

Das da oben könntest du wie das configure in eine Klassenmethode schreiben und dann so wie das configure in nfsd_start() aufrufen.
0
gfhfkgfhfk03.01.2400:37
Allgemein
Für Hilfe zu C++ empfiehlt sich ein das C++ Forum.

Zu dem Code in Previous Projekt
Bei diesem C++ Code wird mir schlecht!

Das Problem ist, dass Du im Grunde ein C Projekt hast, bei dem kleine Anteile in C++ geschrieben sind. Das ist selbst noch kein Problem. Es erfordert aber, dass man den C++ Code so kapselt, dass er keinen Ärger macht. Es geht nicht nur ums Name Mangling sondern vor allem auch ums Exception Handling. Der C Code kann damit rein gar nichts anfangen. Im Unterverzeichnis nfsd ist ja im Grunde ja alles C++ Code. Wenn man die Kommentare liest, dann ist der Code deutlich jünger als 2011 und trotzdem wird die rule of five nicht eingehalten, und so einige Absurditäten sind eingebaut. Das ganze ist extrem im C Stil gehalten und nicht wirklich C++. RAII scheint dem Autoren eher unbekannt gewesen zu sein. Das ist eher ein Beispiel wie man es nicht machen sollte. Dann ist da das Thema wie man C++ Klassen über C APIs exportiert. Auch das ist nicht gut umgesetzt. Dann fällt auf, dass nfsd.h und nfsd.cpp nicht wirklich eine Klasse beinhalten, sondern auf File Ebene mit globalen Variablen hantiert wird.
+2
macuser11
macuser1103.01.2406:23
@gfhfkgfhfk KING 👑
0
andreas_g
andreas_g03.01.2408:22
AidanTale
Danke für das Beispiel! Eigentlich möchte ich aber nicht die ganzen machines beziehungsweise locations ersetzen, sondern jeweils nur die Einträge für NAME_HOST und ntp.

gfhfkgfhfk
Danke für den Tipp mit dem C++-Forum. Wie gesagt verstehe ich nichts von C++. Daher kann ich mit den weiteren Ausführungen nicht viel anfangen. Kannst du den Code verbessern? (sollte nach Möglichkeit auch auf alten Systemen kompiliert werden können, also < C++11 sein).
0
gfhfkgfhfk04.01.2415:09
andreas_g
gfhfkgfhfk
Danke für den Tipp mit dem C++-Forum. Wie gesagt verstehe ich nichts von C++. Daher kann ich mit den weiteren Ausführungen nicht viel anfangen. Kannst du den Code verbessern? (sollte nach Möglichkeit auch auf alten Systemen kompiliert werden können, also < C++11 sein).
Fangen wir mal am wichtigen Punkt an. Auf was für Systemen soll das noch laufen? SDL2 z.B. hat eine C++ Interface Library, die mindestens C++11 voraussetzt. Persönlich würde sehe ich C++11 als Minimum an. Der Bruch zwischen C++03 und C++11 war sehr groß. Wünschenswert wäre eher C++17.

Ich hatte versucht das Projekt auf meinem Hauptsystem Ubuntu 22.04 LTS zu übersetzen. Mittels
svn checkout https://svn.code.sf.net/p/previous/code/trunk previous-code
habe ich den Code geholt und dann im build directory mittels cmake .. und make gebaut. Das führt zu
/usr/bin/ld: CMakeFiles/Previous.dir/main.c.o: in function `Main_ResetKeys':
/home/user/projects/previous/previous-code/src/main.c:452: undefined reference to `SDL_ResetKeyboard'
/usr/bin/ld: CMakeFiles/Previous.dir/main.c.o: in function `Main_HaltDialog':
/home/user/projects/previous/previous-code/src/main.c:186: undefined reference to `SDL_ResetKeyboard'
/usr/bin/ld: CMakeFiles/Previous.dir/main.c.o: in function `Main_ResetKeys':
/home/user/projects/previous/previous-code/src/main.c:452: undefined reference to `SDL_ResetKeyboard'
/usr/bin/ld: CMakeFiles/Previous.dir/fast_screen.c.o: in function `Screen_Init':
/home/user/projects/previous/previous-code/src/fast_screen.c:360: undefined reference to `SDL_GetWindowSizeInPixels'
collect2: error: ld returned 1 exit status
make[2]: *** [src/CMakeFiles/Previous.dir/build.make:845: src/Previous] Fehler 1
make[1]: *** [CMakeFiles/Makefile2:278: src/CMakeFiles/Previous.dir/all] Fehler 2
make: *** [Makefile:136: all] Fehler 2

Dann sind im Projekt etliche Sourcen (auch C++) enthalten, die aus anderen Projekten kommen. Soll das erhalten bleiben, oder was ist das vorgesehen?

Zum Ändern können, sicherlich kann ich das, nur bevor wir darüber reden sollten die Punkte oben geklärt sein.
0
andreas_g
andreas_g04.01.2415:47
Vielen Dank für die Unterstützung!

C++11 wäre aus meiner Sicht in Ordnung. Es wäre schön, wenn C++17 nicht zwingend erforderlich wäre. Wichtig wäre aus meiner Sicht auch, dass der Code möglichst einfach zu warten ist, auch für jemanden, der C++ nur rudimentär beherrscht.

Die gezeigten Fehler beim Linken liegen in einer veralteten Version von SDL2 begründet. Es wird mindestens SDL2 v2.26.0 vorausgesetzt.

Ich bin mir nicht sicher, ob ich die letzte Frage richtig verstehe. Alle Dateien sind Teil von Previous beziehungsweise dem zugehörigen Command-Line-Tool "ditool". Alle sind für die Funktion von Previous erforderlich.
0
gfhfkgfhfk04.01.2422:18
andreas_g
Die gezeigten Fehler beim Linken liegen in einer veralteten Version von SDL2 begründet. Es wird mindestens SDL2 v2.26.0 vorausgesetzt.
Dann haben wir da schon den ersten Bug. cmake sollte die Version prüfen, und eine entsprechende Fehlermeldung liefern.
Im CMakeLists.txt sollte es heißen
find_package(SDL2 2.26.0)
und dann gibt es auch den passenden Hinweis, dass die SDL2 Version nicht passt.
andreas_g
Ich bin mir nicht sicher, ob ich die letzte Frage richtig verstehe. Alle Dateien sind Teil von Previous beziehungsweise dem zugehörigen Command-Line-Tool "ditool". Alle sind für die Funktion von Previous erforderlich.
Es geht darum, ob auch in Zukunft Updates dieses Codes aus den anderen Projekten geplant ist.

Was das Thema Wartbarkeit von C++ Code von jemanden betrifft, der kein C++ kann, das sehe ich eher schwarz.
0
andreas_g
andreas_g04.01.2422:34
Naja, das mit der SDL2-Minimalversion würde im readme stehen. Aber da readme-Dateien bekanntlich nicht gelesen werden, ist der Vorschlag die Version durch CMake prüfen zu lassen vernünftig.

Ich denke eine Minimalvariante um das Aktualisieren von systemType und das optionale Anfügen oder Entfernen der location ntp zu ermöglichen würde genügen. Daher ist ein Eingriff in die anderen Dateien wahrscheinlich nicht nötig. Würde wirklich mehr Zeit in dieser Angelegenheit aufgewendet, wäre eine neue Implementation in C vermutlich die bessere Investition.

AidanTale
Ich habe Folgendes versucht, bekomme aber danach EXC_BAD_ACCESS:
    /* Remove network machines */
    old = m_Network.mRoot.find("name","machines");
    m_Network.mRoot.remove(old[0]);
    
    /* Add network machines for new system type */
    machines = m_Network.mRoot.add(NIProps("name","machines"));
    machinesadd(NIProps("name",hostname) ("ip_address",ip_addr_str(CTL_NET|CTL_ALIAS, 4)));
    machinesadd(NIProps("name",NAME_HOST)("ip_address",ip_addr_str(CTL_NET|CTL_HOST,  4))("serves",NAME_HOST"/local")("netgroups","")("system_type",systemType));
    machinesadd(NIProps("name",NAME_DNS) ("ip_address",ip_addr_str(CTL_NET|CTL_DNS,   4)));
    machinesadd(NIProps("name",NAME_NFSD)("ip_address",ip_addr_str(CTL_NET|CTL_NFSD,  4))("serves","./network,../network"));
0
gfhfkgfhfk08.01.2408:30
andreas_g
Ich denke eine Minimalvariante um das Aktualisieren von systemType und das optionale Anfügen oder Entfernen der location ntp zu ermöglichen würde genügen. Daher ist ein Eingriff in die anderen Dateien wahrscheinlich nicht nötig.
Der gesamte Code im Unterverzeichnis nfsd ist ein ziemlicher Murks. Es gibt keine sauberen C Interfaces und es gibt keine sauberen C++ Interfaces. Wenn ich alleine sehe dass in .cpp Dateien Funktionen deklariert werden, läuft etwas im Programmcode fundamental falsch. Wofür gibt es Header Dateien?

Dann so Dinge wie rohe Zeiger in std::vector Container. Besitzende rohe Zeiger kann man nicht in Standard Container ablegen, dann hat man Leaks. Und genau das fällt Dir hier auf die Füße. Wenn ich mir in nfsd.cc die Funktion add_rpc_program an schaue, was passiert mit den Zeigervariablen udp und tcp? Selbst Dir mit C Kenntnisse muss doch ersichtlich sein, dass zu jedem new auch ein delete im Code stehen muss analog zu malloc und free?

Ich schaue es mir die Woche über genauer an, und hoffe den Code zu fixen zu können.
andreas_g
Würde wirklich mehr Zeit in dieser Angelegenheit aufgewendet, wäre eine neue Implementation in C vermutlich die bessere Investition.
Dir ist schon bewusst, dass Du dann so einiges mehr zu tun hättest, da die C++ Standardlibrary ersetzt werden müsste?
0
andreas_g
andreas_g08.01.2411:02
gfhfkgfhfk
Ich schaue es mir die Woche über genauer an, und hoffe den Code zu fixen zu können.
Danke für die Unterstützung! Die Dateien im nfs-Verzeichnis können verändert werden. Es ist nicht erforderlich, den bereits stark veränderten Code des ursprünglichen Projektes kompatibel zu halten.
gfhfkgfhfk
andreas_g
Würde wirklich mehr Zeit in dieser Angelegenheit aufgewendet, wäre eine neue Implementation in C vermutlich die bessere Investition.
Dir ist schon bewusst, dass Du dann so einiges mehr zu tun hättest, da die C++ Standardlibrary ersetzt werden müsste?
Ja, das wäre sicher ein Stück Arbeit. Dafür wäre danach Code vorhanden, den ich langfristig warten und ergänzen kann. Jetzt bin ich dazu auf Hilfe angewiesen.
0
andreas_g
andreas_g27.01.2413:46
gfhfkgfhfk

Bist Du in dieser Sache noch aktiv?
0
gfhfkgfhfk27.01.2415:13
Ja, mehr per PM
0

Kommentieren

Diese Diskussion ist bereits mehr als 3 Monate alt und kann daher nicht mehr kommentiert werden.