Forum: Compiler & IDEs USB Host in C, was bedeuten diese Zeilen


von HyperMario (Gast)


Lesenswert?

Hallo Freunde des C proggens

Hab hier einen kleinen Ausschnitt aus einem C programm und steh voll auf 
dem Schlauch. Kann mir einer sagen was das bedeutet. (Kommentare von 
mir)
1
// HID callback class declare
2
typedef struct{
3
  void(*DeviceInit)();
4
  void(*ReportReceived)(uint8_t* rptData);
5
} TUSBHostHIDHandler;
6
7
// HID callback class define
8
TUSBHostHIDHandler USBHost_HIDHandler = {
9
  HidDevInit,
10
  HidDevReportReceived
11
};
12
13
// Pointer to struct ?
14
TUSBHostHIDHandler* USBHost_HIDHandlerPtr = &USBHost_HIDHandler;

Das sind so genannte callbacks hinter denen eine compilierte lib von 
Mikroe
steckt.

von Sven B. (scummos)


Lesenswert?

Das sind zwei Function Pointer, die in einem struct gruppiert sind.

von HyperMario (Gast)


Lesenswert?

Sven B. schrieb:
> Das sind zwei Function Pointer, die in einem struct gruppiert sind.

Danke, das bedeutet wohl das damit 2 Funktionen aufgerufen werden.
Warum ist das in einer struct und nicht einzeln?

von Jim M. (turboj)


Lesenswert?

HyperMario schrieb:
> Warum ist das in einer struct und nicht einzeln?

Eventuell braucht man das mehrmals, z.B. einmal für die Maus und einmal 
für die USB Tastatur.

von Sven B. (scummos)


Lesenswert?

HyperMario schrieb:
> Sven B. schrieb:
>> Das sind zwei Function Pointer, die in einem struct gruppiert sind.
>
> Danke, das bedeutet wohl das damit 2 Funktionen aufgerufen werden.
> Warum ist das in einer struct und nicht einzeln?

Das musst du wohl den Autor dieses Codes fragen. Wahrscheinlich fand er 
es praktischer so, weil die Funktionen ja irgendwie zusammen gehören.

von HyperMario (Gast)


Lesenswert?

Vielen Dank das macht es etwas klarer.


Jim M. schrieb:
> Eventuell braucht man das mehrmals, z.B. einmal für die Maus und einmal
> für die USB Tastatur.

Stimmt, da wird später zwischen Maus und Keyboard unterschieden.
Verstehe ich das richtig das er sich eine Struktur mit Funktionspointern 
aufbaut um die später mehrfach zu verwenden?

Also z.B das er sich eine macht wo die Maus callbacks reinlaufen und 
eine für das keyboard. Ist das richtig?


und was meint dieser Teil?
1
  // Pointer to struct ?
2
  TUSBHostHIDHandler* USBHost_HIDHandlerPtr = &USBHost_HIDHandler;

Das verstehe ich so das im hinteren Teil die Adresse von der Struktur 
geholt wird in der die die Functionspointer liegen.

Wofür braucht man das? Man muss doch doch nur die Funktionen aufrufen 
und was bedeutet TUSBHostHIDHandler* ?

von Theor (Gast)


Lesenswert?

HyperMario schrieb:
> Sven B. schrieb:
>> Das sind zwei Function Pointer, die in einem struct gruppiert sind.
>
> Danke, das bedeutet wohl das damit 2 Funktionen aufgerufen werden.

Nein, das bedeutet es so nicht.
Aber siehe zunächst meine Antwort auf Deine zweite Frage.

> Warum ist das in einer struct und nicht einzeln?

Strukturen sind, mal ganz grob gesprochen, genau was das Wort sagt: 
Dinge, die sich aus mehreren anderen Dingen zusammensetzen.

Ein Auto ist ein Beispiel für eine Struktur aus Sitzen, 
Zigarettenanzünder, etcpp. und nicht zu vergessen, dem Motor.

Ein Buch ist ein Beispiel für eine Struktur aus Kapiteln, Absätzen, 
Sätzen, Haupt- und Nebensätzen etcpp.

(Beachte, dass ich die Beispiele auf zwei unterschiedliche Arten 
beschrieben habe. Vielleicht denkst Du darüber mal nach, was der 
Unterschied ist).

Wenn also Strukturen vorliegen, dann weil sie unterscheidbare 
Einzelteile habe.
In der Umkehrung verwendet man Strukturen, wenn man Einzelteile 
zusammenfügen will. Natürlich. :-)

Bei der Programmierung gibt es nun häufig Fälle in denen mehrere 
Variablen beteiligt sind, wenn es gilt einen Vorgang durchzuführen.
Man nehme etwa einen Ringpuffer.
Da gibt es einen Lesezeiger, einen Schreibzeiger und den Puffer selbst.
Es bietet sich nun an, diese drei Variablen in einer Struktur 
organisatorisch zusammenzufassen.
Das hat drei Vorteile:

1. Wenn man einen Puffer anlegt so sind alle notwendigen 
Teilelemente damit erzeugt. Die Variablen für den Lese- und den 
Schreibzeiger und der Puffer selbst. (Das gibt noch ein besonderes 
Problem, aber das lasse ich hier mal weg).

2. In dem besonderen Fall, dass man mehrere Puffer anlegt, sind durch 
die Zusammenfassung aller Teilelemente, die Puffer insgesamt klar 
unterscheidbar, d.h. man sieht beim lesen, was sich worauf bezieht.

3. Textuell, also in der Organisation des Quellcodes sind immer alle 
notwendigen Elemente beisammen . Man muss also nicht erst immer gucken 
wo man diese oder jene Variable deklariert bzw. definiert hat (und wie 
sie heissen).


So. Ich komme nun auf die erste Frage zurück.

Dein Beispiel legt eine Struktur von Zeigern auf Funktionen an. Mit so 
einem Zeiger kann man zwei Dinge tun.
1. Man kann den Zeiger ändern, d.h die Funktion ändern und damit das 
beeinflussen was geschieht.
2. Man kann diese Funktion(en) aufrufen, damit sie tut, was sie eben tun 
soll.

Aber: In C geht es nicht, wenn man zwei (oder mehr) Funktionszeiger in 
der Struktur hat, dass alle Funktionen auf einen Schlag aufgerufen 
werden - und damit gleichzeitig oder nacheinander ausgeführt werden.

Die Antwort auf die erste Frage ist also: Nein. Das geht nicht.

Was mittlerweile in C wohl geht, ist, die Werte mehrerer 
Mitgliedervariablen der Struktur in einer Anweisung zu setzen.
Man kann auch schon immer, eine Struktur komplett kopieren oder 
initialisieren.

Aber aufrufen bzw. ausführen kann man die Funktionen, auf welche die 
Zeiger zeigen nicht auf einen Schlag - d.h. nicht mit einer 
einzelnen Anweisung. Dazu sind so viele Anweisungen nötig, wie es Zeiger 
auf Funktionen in der Struktur gibt.

von HyperMario (Gast)


Lesenswert?

Danke erstmal für die Antwort, verstehe ich so das Strukturen dazu da 
sind es dem Progger/Leser leichter zu machen. Dem Prozessor ist das 
egal.


Theor schrieb:
> Die Antwort auf die erste Frage ist also: Nein. Das geht nicht.
>
> Was mittlerweile in C wohl geht, ist, die Werte mehrerer
> Mitgliedervariablen der Struktur in einer Anweisung zu setzen.
> Man kann auch schon immer, eine Struktur komplett kopieren oder
> initialisieren.
>
> Aber aufrufen bzw. ausführen kann man die Funktionen, auf welche die
> Zeiger zeigen nicht auf einen Schlag - d.h. nicht mit einer
> einzelnen Anweisung. Dazu sind so viele Anweisungen nötig, wie es Zeiger
> auf Funktionen in der Struktur gibt.

Ein Funktion zur Zeit, soweit so klar.


Aber was macht diese Zeile?
1
 // Pointer to struct ?
2
   TUSBHostHIDHandler* USBHost_HIDHandlerPtr = &USBHost_HIDHandler;

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Die deklariert einen Pointer (USBHost_HIDHandlerPtr) und initialisiert 
ihn mit der Adresse der Strukturinstanz USBHost_HIDHandler.

Das ist stinknormales C und macht effektiv dasselbe wie das hier:
1
int x = 4;
2
3
int *y = &x;

Statt "int" wird in Deinem Beispiel halt der Strukturtyp 
"TUSBHostHIDHandler" verwendet.

von HyperMario (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> Die deklariert einen Pointer (USBHost_HIDHandlerPtr) und initialisiert
> ihn mit der Adresse der Strukturinstanz USBHost_HIDHandler.

Danke, ist jetzt klar.

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.