Vergleich zweier Struct-Variablen

Hallo zusammen,
folgende Ausgangssituation: Ich habe einen Struct, der durch eine Bibliothek aktualisiert wird. Nun möchte ich herausfinden ob sich ein beliebiger Member durch diese Aktualisierung verändert hat. Also definere ich einen zweiten Struct gleichen Typs und kopiere vor der Aktualisierung den aktuellen Struct hinein.
Das Ganze schaut als Beispiel so aus:

struct MY_DATA { 
  uint8_t button_01; 
  int8_t joystick_01_x; 
  int8_t joystick_01_y; 
  uint8_t button_02; 
  int8_t value_01;
  uint8_t connect_flag;  
} actData;

struct MY_DATA prevData;

// ...

prevData = actData;
// actData wird nun aktualisiert 

Nun möchte ich eine Funktion erstellen, die als Parameter einen beliebigen Member aus dem Struct "actData" aufnimmt und ihn mit dem entsprechenden Member des Structs "prevData" vergleicht.

// blueprint

bool isEqual(actData.<Member>){
return actData.<Member> == prevData.<Member>
}

Gedanklich bin ich da bei Templates und/oder Pointern, aber irgendwie habe ich da ein Brett vorm Kopf. Könntet ihr mir bitte auf die Sprünge helfen? :smiley:

Liebe Grüße Cox

was wäre kürzer (hätte weniger LoC) als im Anlassfall ein

 if (actData.connect_flag == prevData.connect_flag) 

?

Ich möchte die Funktion ja universal halten und deshalb einen beliebigen Member angeben können. Zumal bei Erweiterung des ganzen auch noch andere Member hinzu kommen könnten.

Du möchtest nicht für jeden EIntrag einen Vergleich.
Dafür gibt es memcmp();

Doch, genau das möchte ich :smiley:

Dann musst Du sowieso den jeweiligen member übergeben.
Und dann macht das eine ganz normale Funktion.

ich bin gespannt auf andere Vorschläge.
Aber so rein aus dem Bauch: Ein Pointer auf actData.connect_flag zeigt wo anders hin als ein pointer auf prevData.connect_flag, also müsstest du deiner Funktion zwei Pointer übergeben.

mit einem Template ... nur das Member übergeben und in der Funktion dann auf beide structs abfragen ... mal beim @combie anklopfen ... oder googeln.

also memcmp

Ich habe folgende Krücke, die funktioniert:
Ich kopiere das Struct "actData" in ein Array, hole mir per offsetof den Array-Index des jeweiligen Member und lese ihn dann aus... funktioniert tadellos - ABER das muss doch irgendwie eleganter gehen :roll_eyes:

Ich danke für das Vertrauen.
Denke aber nicht, dass Templates hier wirklich eine Lösung sind.

Gegenvorschlag:
Mit Settern arbeiten, dann weiß die Struktur selber welche Elemente geändert wurden.

Vielleicht könne man auch mit offsetof() was basteln, aber das wird sicherlich unschön.

Was meinst du damit?
Auf die Struktur selbst bzw. deren Aktualisierung habe ich keinen Einfluss, die wird mir durch die Bibliothek quasi so vor die Nase gesetzt.

Das ist ein Widerspruch!

Die Lib ist offensichtlich geheim, Gott gegeben, unveränderlich und gleichzeitig doch auch veränderlich.

1 Like

Herrgott :laughing: ...geht die Erbsenzählerei wieder los.
Wir spulen nochmal ganz zurück. Die Struktur stammt von der Seite RemoteXY. Je nachdem welche und wie viele Elemente im Online-Editor platziert werden wird die Struktur automatisch generiert und dessen Bibliothek mit auf den Weg gegeben - also ist diese fix zur Kompilierung, kann aber beliebig oft die Form ändern.
Ich möchte speziell für die Button eine Flankenabfrage implementieren (positiv & negativ) und dafür benötige ich nunmal den Wert des Members vor der Aktualisierung um die entsprechenden Vergleiche durchzuführen.

Wenn Du die Struktur generiert bekommst, um sie in Deinen Code einzubauen, dann kannst Du die Getter und Setter doch selbst noch einbauen.

Gruß Tommy

Dann musst du doch wissen, was und wo der Status eines Button in der struct ist. Das passt nicht dazu, dass der Aufbau der struct sich ändern kann, ohne dass du das weißt.

Irgendwie habe ich das Gefühl wir reden aneinander vorbei.
Deshalb möchte ich doch den Namen der Variablen angeben können, damit es eben egal ist an welcher Stelle im Struct just dieser Member steht. Wie gesagt... die Krücke über ein Hilfsarray und offsetof habe ich und das funktioniert auch, es ist halt nur nicht "schön".
Können wir also bitte zurück zu meiner Frage kommen: Geht folgendes - und falls ja, wie?

Die Frage wurde beantwortet.
Ich versteh nicht warum Du das nochmal aufrollen musst.

Hallo,

suchst du sowas?

struct MyData { 
  uint8_t x; 
  int8_t y; 
  int8_t z; 
};

MyData actData;
MyData prevData;

bool vergleich (const MyData a, const MyData b) {
  bool state {true};
  if (a.x != b.x) { state = false; }
  if (a.y != b.y) { state = false; }
  if (a.z != b.y) { state = false; }    
  return state;
}

void setup (void)
{
  const bool i = vergleich (prevData, actData);
}

Den Vergleich ob == oder != oder den Rückgabewert true oder false kannste halten wie Nolte.

Wenn man etwas sucht sollte auch das funktionieren.

struct MyData { 
  uint8_t x; 
  int8_t y; 
  int8_t z; 
  friend auto operator<=>(MyData const&, MyData const&) = default;
  friend auto operator==(MyData const&, MyData const&) -> bool = default;
};

MyData actData;
MyData prevData;

void setup() { 
  const bool i = (actData == prevData? true : false);
}

Womöglich kompiliert das 2. bei euch nicht.
Dann könnte man es noch so machen

struct MyData { 
  uint8_t x; 
  int8_t y; 
  int8_t z; 
};

MyData actData;
MyData prevData;

bool vergleich (const MyData a, const MyData b) {
  if ( (a.x == b.x) 
    && (a.y == b.y)
    && (a.z == b.y) )
  return true;
  else return false;
}

void setup() {
  const bool i = vergleich (prevData, actData);
}

Damit muss er aber mit jeder neuen Structur, die er erstellt auch den Code für die Vergleiche neu bauen - und das will er ja nicht.
Und auch das auswerten über ALLE Member ist nicht gewollt, denn das kann memcmp() in einem Rutsch ohne Angabe der einzelnen Member, was er ja ausgeschlossen hat.

das vergleicht doch alle 3 member oder?

Er will EIN Member der Funktion übergeben und nur dieses eine Member soll mit dem gleichlautenden Member der anderen Struktur verglichen werden.