Forum: Compiler & IDEs Kollision zweier Typendefinitionen vermeiden


von Florian (Gast)


Lesenswert?

Morgen!

Ich habe hier eine ziemliche Kopfnuss...
Ich habe einen vorgefertigten Quellcode, der verschiedene Module 
beinhaltet. Diese Module kann man je nach Bedarf zuschalten.

Nun will ich Modul A und Modul B in meinem Programm zuschalten. Dabei 
wird zuerst A abgearbeitet und abgeschlossen, bevor das Selbe mit B 
passiert.

Mein Problem nun:
Beide Module definieren per typedef ein neues Synonym mit identischem 
Namen, allerdings abgeleitet von unterschiedlichen Datentypen.

Das sieht im Code so aus:
1
// Allgemeiner header: uip.h
2
struct uip_udp_conn
3
{
4
  //... einige Variablendeklarationen
5
  uip_udp_appstate_t appstate;  // die 'kritische' Deklaration
6
};
7
8
9
// Modul A: Ein DHCP-Client dhcp.h
10
typedef struct dhcpc_state uip_udp_appstate_t;
11
12
13
// Modul B: Ein DNS-resolver resolv.h
14
typedef int                uip_udp_appstate_t;

Da jedoch die Module A und B hintereinander abgearbeitet werden, wäre 
es doch sicher irgendwie möglich, dass uip_udp_appstate_t zuerst ein 
Synonym von 'struct dhcpc_state' und anschließend von 'int' ist.

Nur wie kann man soetwas am geschicktesten umsetzen ohne massiv in den 
bestehenden Quelltext einzugreifen?
Der Code ist umfangreich, große Änderungen sollten vermieden werden. Am 
besten Auslagern auf zusätzliche Funktionen. Aber irgendwie find ich 
keinen richtigen Ansatz :(

So, jetzt seid Ihr gefragt!
Vielen Dank im Vorraus!

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

1) Demjenigen, der das Konzept gemacht hat, nen Tritt in den A verpassen 
:o)
2) In zwei Modulen. Das eine verwendet typedef A, das andere typedef B. 
In einem der beiden Module (oder in einem dritten) wird die Ausgabe nach 
A resp. B delegiert. Das sollte gehen, weil A und B nacheinander 
verwendet werden.

Johann

von Karl H. (kbuchegg)


Lesenswert?

Eventuell eine Zwischenschicht einziehen, sodass der Compiler nie beide 
'Module' gleichzeitig zu sehen bekommt. Hilfreich kann es dabei sein, 
jedes Modul einzeln in eine Library zu verpacken und für jedes Modul 
eine neue HeaderDatei schreiben, die die Zwischenschicht nach aussen 
kommuniziert und nichts von den originalen Headern benutzt.

Schön ist das nicht, übersichtlich ist es auch nicht unbedingt und 
Laufzeit wird man damit höchstwahrscheinlich auch verlieren.

Aber wie Johann L. schon sagte: Dem, der sich das ausgedacht hat, einen 
nassen Fetzen solange um den Schädel dreschen, bis nur noch Fasern 
vorhanden sind.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Karl heinz Buchegger wrote:

> Schön ist das nicht, übersichtlich ist es auch nicht unbedingt und
> Laufzeit wird man damit höchstwahrscheinlich auch verlieren.

Spätestens im Debugger wird man sein Blaues Wunder erleben...

von Andreas V. (tico)


Lesenswert?

Es sollte doch möglich sein, die beiden Module einfach in verschiedene 
namespace zu verpacken.

von Klaus W. (mfgkw)


Lesenswert?

aber nicht in C

von Karl H. (kbuchegg)


Lesenswert?

Andreas Vogt wrote:
> Es sollte doch möglich sein, die beiden Module einfach in verschiedene
> namespace zu verpacken.

* Namespaces gibt es nur in C++, nicht in C
* Hast du sowas schon mal gemacht?
  Wenn nein: probiers mal - viel Spass

Da ist es noch einfacher ein Testprojekt aufzusetzen in dem nur ein 
'Modul' verwendet wird, dann einen der Datentypen umzubenennen und 
solange nachzueditieren, bis der Compiler nicht mehr meckert.
Passieren kann dabei nicht viel, der Compiler findet alle Stellen, an 
denen sich die Änderung auswirkt und die meisten Änderungen werden sich 
mit einem globalen 'Replace' im Editor erledigen lassen. Es ist unter 
Umständen zeitaufwändig, aber machbar. Eigentlich sollte man den, der 
das ursprünglich verbrochen hat, dazu verdonnern genau das jetzt zu tun.

von Andreas V. (tico)


Lesenswert?

Karl heinz Buchegger wrote:
> * Namespaces gibt es nur in C++, nicht in C

Das ist schon klar, aber mit Hilfe von extern "C" kann man die beiden ja 
auch bunt mischen. Vieles, was eigentlich als C-Code gedacht war lässt 
sich ja auch mit dem c++-Compiler fehlerfrei übersetzen. Ich glaube 
auch, dass diese Lösung weniger Klimmzüge erfordert als andere.

Gruss
Andreas

von Wolfgang Mües (Gast)


Lesenswert?

Florian,

das ist ja ein schöner Mist! Da kann man nur sagen: schlechtes Design!

Wie man es richtig macht:

uip_udp_appstate_t ist ja anscheinend der interne Status einer UDP 
Anwendung.

Dann gehört diese Statusdefinition NICHT in eine Headerdatei, die 
außerhalb der Anwendung verwendet wird - das macht man nicht!

Solche Probleme löst man in C in allgemeingültiger Form mit Zeigern auf 
nicht spezifizierte Strukturen:

also z.B. in einer allgemeinen Headerdatei:

struct uip_udp_appstate_t; /* also OHNE Inhalt */

Dann kann man einen Pointer auf diese Struktur in einer allgemeinen 
Datenstruktur aufnehmen:

struct {
struct uip_udp_appstate_t * appstate;
}....;

Jede Anwendung kann nun für sich eine private Deklaration von struct 
uip_udp_appstate_t einführen. Natürlich gehören dann die Methoden zum 
Allozieren und Freigeben dieser Struktur auch in den Scope der 
Anwendung.

Viele Grüße

Wolfgang

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.