Nun sollen diese Variablen einem struct zugeordnet werden (Menüstruktur)
1
structmenuepunkt
2
{
3
void*name;
4
void*variable;
5
void*einheit;
6
};
7
8
structmenuepunkthauptmenue[]=
9
{
10
{&str_var1,&var1,&str_degree},
11
{&str_var2,&var2,&str_degree},
12
{&str_var3,&var3,&str_kmh},
13
{&str_var3,&var4,&str_v}
14
};
Nun mochte ich die Werte auf die die Zeiger der Variablen zeigen
auslesen.
Normalerweise mache ich das so:
1
uint8_tvariable=(uint8_t)var1;
Da meldet der Compiler aber : "cast from pointer to integer of different
size"
Was mache ich falsch?
Noch eine Frage:
Kann ich irgendwie herausfinden ob var1 als uint8_t oder uint16_t
definiert ist?
Danke
Tach!!
Wenn du auf globale Variablen zugreifen willst, solltest du die
Schreiblesezugriffe sorgfältig planen, zB so:
volatile * const unsigned char var1 = [Adresse]
Nun soll eine Menüstruktur abgebildet werden:
typedef struct manu{
blafasel m_name;
blafasel m_var;
blafasel m_einheit;
}
es gibt eigentlich keinen typ namens blafasel. Hier sollte man etwas
richtiges einsetzen. Sicer hast du etwas geeignetes auf Lager.
Von diesem Typ kann amn dann alles andere ableiten. Ein neues menüitem
wird angelegt, indem es von der typedef erzeugt wird und dann mir Daten,
die über edie zeiger eingelesen werden, gefüllt wird.
Grüsse
Robert
Also Tobi,
das Grundproblem bei Deiner Frage wird zunächst einmal der folgende Link
abdecken.
Beitrag ""Hilfe", "funktioniert nicht", funktioniert nicht."
Zusätzlich:
>Nun mochte ich die Werte auf die die Zeiger der Variablen zeigen>auslesen.>Normalerweise mache ich das so:
1
uint8_tvariable=(uint8_t)var1;
Mit dem obigen Programmtext bekommst Du diesen Fehler garantiert nicht!
Denn hier gibt es garkeinen cast von einem Zeiger. D.h. Du machst das
auch nicht "normalerweise" so. Das funktioniert auch schon deswegen
nicht mit Deinem Array von structs, da weder ein Index noch ein Punkt
noch ein '*' erscheint.
>Kann ich irgendwie herausfinden ob var1 als uint8_t oder uint16_t>definiert ist?
Dazu brauchts Du nur Deinen eigenen Programmtext lesen. Warum fragst Du
das?
Tobi schrieb:
> Kann ich irgendwie herausfinden ob var1 als uint8_t oder uint16_t> definiert ist?
Nein, kannst du nicht. In C gibt es keine Reflection.
Du musst dir in deine Struktur einen entsprechenden Eintrag machen, aus
dem du den Datentyp rausfindest. In der Verwendung benutzt du dann
diesen Eintrag um dir den Datentyp des Pointers zurechtzucasten.
Für alle anderen Pointer, bei denen feststeht, auf welchen Typ sie
zeigen benutzt du keinen void Pointer.
Die Lösung von Karl heinz Buchegger find ich eigentlich sehr schön!
schön zu verstehen und transparente Vorgehensweise.
Wobei ich mir mit (void*) Pointern immer ein bisschen schwer tue.
(void*) heisst ja nur, leg einen Pointer mit der Adressbreite des
Mikrocontrollers an, also soweit mir bekannt.
Bei einem 8 Bit System wäre das dann standardmäßig ein Pointer auf einen
8 Bit Wert. Soweit richtig, oder?
Ist dann sichergestellt, dass, wenn ich auf eine 16 Bit Variable mit
diesem Pointer zugreife:
1
void*test_pointer;// 8 Bit System
2
3
staticuint16_tvar_16=500;
4
5
voidmain(void)
6
{
7
test_pointer=&(var_16);// Erhaelt die Adresse wo die 16 Bit Variable liegt
8
9
(*test_pointer)++;// direkter Zugriff
10
11
// oder
12
13
(*((uint16_t*)(test_pointer)))++;// erst Pointer cast und dann Zugriff
14
15
}
Was würde bei Fall 1 passieren? Hab leider gerade keinen C Compiler zur
Hand ;-)
Also ich würde denken:
Er behandelt die Variable wie einen 8 Bit Wert:
500 : MSB / LSB : 0x01F4 : 01 F4
Also Ergebnis würde also bei Fall 1: 2 rauskommen?
und bei Fall 2: 501 ?
Gruß
Sebastian B. schrieb:
> Wobei ich mir mit (void*) Pointern immer ein bisschen schwer tue.
ein void * ist einfach nur ein Pointer, der eine Adresse enthält. Es ist
aber nicht festgelegt, welchen Datentypen man vorfindet, wenn man den
Pointer dereferenziert. In diesem Sinne ist ein void Pointer ein
generischer Pointer.
> Bei einem 8 Bit System wäre das dann standardmäßig ein Pointer auf einen> 8 Bit Wert. Soweit richtig, oder?
Nein. Ein void Pointer trifft keine Aussage darüber, was an der
entsprechenden Speicherstelle auf die er zeigt zu finden ist.
> void * test_pointer; // 8 Bit System>> static uint16_t var_16=500;>> void main (void)> {> test_pointer = &(var_16); // Erhaelt die Adresse wo die 16 Bit Variable> liegt>> (*test_pointer)++; // direkter Zugriff
Das geht nicht.
Einen void Pointer kann man nicht dereferenzieren.
Um das tun zu können, muss der Pointer auf einen speziellen Datentyp
zeigen. void leistet das nicht.
> (*((uint16_t*)(test_pointer)))++; // erst Pointer cast und dann Zugriff
so gehts.
Du hast aus dem generischen 'Ich zeige auf irgendwas' Pointer einen
Pointer gemacht, der auf einen uint16_t zeigt.
> Was würde bei Fall 1 passieren?
Gar nichts, du kriegst das nicht durch den Compiler.