www.mikrocontroller.net

Forum: Compiler & IDEs Vererbung in C? (allgemein, nicht nur GCC)


Autor: Be Bo (bebo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

gibt es einen offiziellen Weg folgendes in C zu realisieren?

Ich habe mehrere Hardwarekomponenten (UART, USB, ...).

Alle können Datenströme senden und empfangen. D.h. für jede 
Hardwarekomponente gibt es ein struct, welches die Komponente verwaltet.
Nun haben diese structs gemeinsamme Elemente. Z.B. verfügt jede 
Hardwarekomponente über einen Send- und Empfangspuffer + dazugehörige 
Pointer. Diese sind für alle Hardwarekomponentet/structs gleich.

Nun möchte ich eine C-Funktion schreiben, der ich jede dieser 
verschiedenen structs übergeben kann.
Wichtig wäre da aber, daß z.B. der RxBuffer in allenen structs den 
gleichen Offset hat.

In C++ würde man da ja z.B. eine struct/class entwerfen, die dieses 
gemeinsammen Elemente enthält. Alle speziellen structs/classes würden 
dann von dieser erben.
Somit könnte man der Funktion einen Pointer vom Typ Basisklasse 
übergeben und man kann sicher sein, daß die in der Basisklasse 
deklarieretn Elemente für alle Hardwarekomponenten an der gleichen 
stelle liegt.

Wie macht man das in C?

Autor: der mechatroniker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eklige Variante: cast

Bessere Variante: die gemeinsamen Komponenten in einer Unter-Struct 
zusammenfassen, von der dann eine Instanz in jeder Haupt-Struct ist. Der 
Programmteil, der keine Unterscheidungen macht, bekommt dann einen 
Zeiger auf diese Unter-struct.

Autor: Be Bo (bebo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe ich mir schon gedacht. Ich hatte aber gehofft, daß ich die doppelte 
Indirektion umgehen kann.

Kann man ich eigentlich darauf verlassen, daß die oberen struct-Member 
in verschiedenen structs, wenn sie gleich sind, immer den gleichen 
Offset haben?

Autor: chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du definierst ein Struct, als CPP define z.B. und verwendest es.
Nicht elegant, aber portable.

#define HW_CLASS \
 int size; \
 int used;
 char* head; \
 char* foot; \
 char buff[0]

Wenn der/die Compiler alle unnamed structures unterstützt, dann 
definiere
eine Struct, und instanziere es, das ist sauberer, aber nicht portabel.

Autor: Be Bo (bebo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@chris:
Was meinst Du mit "als CPP define"?
Und was meinst Du mit "sauber, aber nicht portabel"? Solange es die 
Compiler unterstützen und ich den Datenblock nicht blind auf ein anderes 
System übertrage, sollte es doch gehen, oder?

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die einzelnen IO-Typen (oder Zeiger darauf) in eine Union stopfen?

#include "usb.h"
#include "uart.h"
#include "i2c.h"
...

enum
{
    IO_USB,
    IO_UART,
    IO_I2C,
    ...

    IO_NIL
};

typedef union
{
    int id;

    struct
    {
        int id;
        usb_t data;
    } usb;

    struct
    {
        int id;
        uart_t data;
    } uart;

    ...

} io_t;

void handle_io (io_t * io)
{
    switch (io->id)
    {
        case IO_USB:
            io->usb.data.buffer[0] = '0';
            break;

        case IO_UART:
            io->uart.data.buffer[0] = '0';
            break;

        ...

        default:
            fatal_error();
            break;
    }
}

Das ist keine Verebung, aber es gibt dir verschiedene Sichten auf dein 
io-Objekt. Und in uart.h:
#include "buffer.h" // extern char buf[];

typedef struct
{
    ...
    char * buffer;
    ...
} uart_t;

void uart_init (uart_t * uart)
{
    uart->buffer = buf;
    ...
}

Autor: chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Was meinst Du mit "als CPP define"?
einfach eine preprozessor define, habe dir ein Beispiel dort gemacht.
struct hw_serial { HW_CLASS; char dummy[100]; } hw_serial1,hw_serial2;

>Und was meinst Du mit "sauber, aber nicht portabel"? Solange es die
>Compiler unterstützen und ich den Datenblock nicht blind auf ein anderes
>System übertrage, sollte es doch gehen, oder?

Ja, wenn es deine Compiler unterstützen.

Z.B.

struct hw_base { int size; char *head; char*tail; ... };

struct hw_rs232 { struct hw_base; int port; ... } serial1, serial2;

dann kannst du im Code z.B.  serial1.size usw benutzen, als hättest du
sie in hw_rs232 declariert.

Bei neueren Branches des GCC kann es sein, daß du -fms-extensions als
Kommandozeile übergeben mußt, damit er das macht, früher konnter es es 
auch
ohne.

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Johann L. schrieb:

> Das ist keine Vererbung, aber es gibt dir verschiedene Sichten auf dein
> io-Objekt. Und in uart.h:

.uart.data.buffer und .usb.data.buffer liegen nicht notwendig an der 
gleichen Adresse (was auch nicht nötig ist) aber sie zeigen auf die 
gleiche Adresse, wenn diese Zeiger richtig initialisiert wurden (siehe 
unten). Beachte, daß das dann nicht reentrant-fähig ist.

Autor: Be Bo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, so,..

... und da sag noch einer, für Microcontroller brauche man kein C++. 
Dabei könnte das Leben doch so einfach sein.

Dann fang ich mal an mir eine Lösung zu stricken ;-)

Autor: chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was hindert dich daran, den mikrocontroller in c++ zu programmieren ?

Autor: chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Auch ich habe schon Pic uC in C++ programmiert, und der ist bei
weitem limitierter als AVR.

Autor: der mechatroniker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Habe ich mir schon gedacht. Ich hatte aber gehofft, daß ich die doppelte
> Indirektion umgehen kann.

Ein CPP-Compiler macht bei Vererbung nix anderes.
Aus
class Dings : public class Bums {
   int some_field;
};

...
Dings d;
Bums *b = &d;

wird
struct Dings {
   struct Bums _base;
   int some_field;
};

...
struct Dings d;
struct Bums *b = &(d._base);

Da bei Einfachvererbung das Basisobjekt an den Anfang des Gesamt-Structs 
gepackt wird, ist diese Indirektion übrigens im Maschinencode recht 
trivial ;-)

Und, wie schon von den Vorpostern genannt: Nimm nen C++-Compiler. Du 
musst ja außerhalb dieser Stelle keine C++-Features nutzen, von daher 
hat dies auf die Codegröße keine negativen Auswirkungen.

Autor: Be Bo (bebo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gibt es denn einen C++ Compiler für die PIC32? Der C32 can kein C++ :-(

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
pic32 sowie pic18 Compiler ist GCC (Gnu C Compiler), man bekommt auch 
die Sourcen. Klar kann der C++. Bei pic24 sowie pic3x weiß ich nicht, ob 
das
GCC ist, oder nicht. Warscheinlich.

Autor: Michael H. (morph1)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
der gcc ist ein c compiler
der g++ ist ein c++ compiler

der c18 ist KEIN gcc, der pic24 aka c30 ist ein gcc derivat

die anderen angaben stimmen

irgendwie verwaschen das thema, auf jedenfall ist der c18, c30 und c32 
KEIN C++ compiler

Autor: chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier ein Thread mit Beispielprogramm am Schluss über das 
objektorientierte Programmieren in C:

Beitrag "Objekte in C"

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> der gcc ist ein c compiler
> der g++ ist ein c++ compiler

und die GCC ist alles zusammen (Gnu Compiler Collection)

Autor: morph1 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
na dann anders ausgedrückt, die gcc die microchip liefert kann kein c++ 
:)

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.