ich habe ein Problem und hoffe Ihr könnt mir weiterhelfen. Ich habe ein Tabelle, wo die Adressen von Parametern abgelegt sind. Es sind 8, 16 und 32-Byte-Parameter. Für die Definition der Tabelle habe ich die größten Wert verwendet (32 Bit).
1
structknx_dp_def
2
{
3
UINT32u32_ID;
4
UINT8u8_Len;
5
UINT8u8_Sonder;
6
UINT32*p32_Parameter;// Zeiger auf Parameter
7
};
8
externstructknx_dp_defknx_dp[KNX_MAX_DP];
Damit der Compiler nicht meckert, habe ich vor jeder Variablen einen Cast vorgesetzt (auch bei den 32-er Variablen - schadet ja nicht):
Soweit so gut. Nun will ich aber Werte in die entsprechenden Parameter schreiben (in meinem Fall empfangene KNX-Daten). Damit ich weiß, wie groß der Parameter ist, habe ich eine Längenangabe in der Tabelle abgelegt (8, 16, 32). Die Info verwende ich auch, um den Wert entsprechend zu casten:
Das funktioniert prinzipiell: aber der Zeiger verändert 32-Bit im RAM, auch wenn ich 8 oder 16 Bit habe. Wie bringe ich den Zeiger dazu, dass er nur 8 oder 16 Bit verändert? Geht das überhaupt irgendwie mit einem Cast? Ich habe schon selbst herumexperimentiert, aber keine Lösung gefunden. Mit Zeigern habe ich immer mal wieder etwas Verständnis-Schwierigkeiten.
Du musst den Zeiger für den Zugriff selbst casten. Natürlich muss (je nach Architektur) der Zeiger selbst passend ausgerichtet sein für die jeweilige Objektgröße.
Sinnvoller wäre es, eine union aus Zeigern der unterschiedlichen Größen zu machen und dann das passende union tag auszuwählen.
Sinnvoller wäre es, eine union aus Zeigern der unterschiedlichen Größen
zu machen und dann das passende union tag auszuwählen.
Vielen Dank für den Tipp.
In meiner Tabelle kommen nun aber Warnungen bei allen definierten Parametern, die mehr als 8 Bit haben (siehe Bild). Was muss ich da angeben, damit es passt?
Die zusätzlichen {} würde ich hier sehr empfehlen, das mögen die Compiler, und macht alles etwas einfacher.
Zuletzt noch zur id. Stimmt dessen Wert mit dem Offset des Eintrags überein? (also ist uiDatapoint == knx_dp[uiDatapoint].id?) Den dann könnte man den aus knx_dp_def weg lassen:
Und zum Pointer, braucht es den Pointer wirklich? Falls der Pointer mindestens 32bit braucht, und man in knx_dp_def einfach uint32_t parameter nehmen würde, würde das sogar Speicherplatz sparen, und man bräuchte keine Casts mehr.
Du siehst schon, Weglassen der "ungarischen" Notation würde die Zeilen etwas verkürzen …
Du kannst natürlich .parameter.ptr32=NULL explizit schreiben, aber bei einer teilweisen Initialisierung einer struct werden implizit alle nicht genannten struct tags eh mit 0 bzw. NULL bzw. 0.0 gefüllt, insofern ist die Angabe dort unnötig, zumal in diesem Falle ja "parameter" eh nicht ausgewertet werden wird.