mikrocontroller.net

Forum: Compiler & IDEs Kollision zweier Typendefinitionen vermeiden


Autor: Florian (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
// Allgemeiner header: uip.h
struct uip_udp_conn
{
  //... einige Variablendeklarationen
  uip_udp_appstate_t appstate;  // die 'kritische' Deklaration
};


// Modul A: Ein DHCP-Client dhcp.h
typedef struct dhcpc_state uip_udp_appstate_t;


// Modul B: Ein DNS-resolver resolv.h
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!

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Andreas Vogt (tico)
Datum:

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

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
aber nicht in C

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Andreas Vogt (tico)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Wolfgang Mües (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.