Zum Inhalt springen
View in the app

A better way to browse. Learn more.

Fachinformatiker.de

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

von void* gecastete struct* prüfen

Empfohlene Antworten

Veröffentlicht

hallo zusammen.

zur zeit schreib ich rechd viele fragen, aber mir fallen sachen ein, die ich nich brauch und mir fallen sachen nicht ein, die ich einfach brauch.

situation:

eine funktion hat n void-pointer. dieser wird je nach anlass zu nem struct gecastet (verschiedene).

frage:

ist es möglich neben prüfung ob dieser NULL ist auch das prüfen ob es die richtige struct ist?

ansonsten kann man ja den größten blödsin casten ^^

Gegenfrage: wie soll das funktionieren?

Der Compiler kann ja schließlich nicht hellsehen...

Stell Dir die Sache mal bildlich vor:

Ein Void-Pointer ist quasi wie ein Notizzettel. Ich schreibe Dir einen Zettel auf dem steht, daß Du bitte in den Keller gehen sollst, mir den Inhalt meines Schuhkartons Nummer 3 mitbringen sollst. Nun darfst Du anhand des Zettels erraten, was genau ich haben will ... ;)

schad schad .....

das blöde man kann ja auch keine feste werte dem vorinitialisieren ... sonst hätte ich dem direkt ne "id" verpassd :/ würde ich die bib nur für C++ un nich noch für C schreiben, könnte ich klassen machen ... aba so :/...

danke trotzdem ^^

situation:

eine funktion hat n void-pointer. dieser wird je nach anlass zu nem struct gecastet (verschiedene).

frage:

ist es möglich neben prüfung ob dieser NULL ist auch das prüfen ob es die richtige struct ist?

Übergib doch einfach noch n enum-Werte, um welchen Typ es sich bei der data[n]:type[n]-Verbindung handelt. :floet:

würde ich die bib nur für C++ un nich noch für C schreiben, könnte ich klassen machen ... aba so :/...
Wenn du Klassen als Void-Zeiger übergibst, hast du dasselbe Problem.

In C++ könntest du das Problem vielleicht eher durch Überladung lösen.

Kannst du nicht für jede Struktur eine eigene Funktion einführen?

Wenn du Klassen als Void-Zeiger übergibst, hast du dasselbe Problem.

*Mein Post noch mal durchles* K ich habs etwas ungenau geschrieben. Das mit den Klassen is auf die vordefinierte Variable bezogen :) Ansonste hätte ich sicherlich die gleiche Probleme wie bei Strukturen

In C++ könntest du das Problem vielleicht eher durch Überladung lösen.

Kannst du nicht für jede Struktur eine eigene Funktion einführen?

Also dass ich entsprechend der struktur, die übergeben wird eine entsprechende funktion schreib? Problem ist ja, dass daas Programm unter C laufen soll, kann eine Überladung nicht eingesetzt werden (deswegen void*)

würde ich explizit für jede Art a funktion schreiben (mit entsprechenden funktionsnamen) ist bei der bibliothek nach aussen hin mehrere Funktionen sichtbar. Dies wollte ich jedoch vermeiden. Nach aussenhin gibt es nur eine Funktion, die aufgerufen werden kann.

weils schöner aussieht :)

Ne...

Das is leider eine vorgabe vom Projekt

Da nach deinen eigenen Angaben die Möglichkeit mit mehreren Funktionen ausfällt, würde ich die Lösung von TDM in Betracht ziehen, also einen zusätzlichen Paramter übergeben welcher die Struktur identifiziert.

Ich wollte hier blos nochmal eine Lösung zeigen, die Microsoft oft in iherer API verwendet. Die geben einfach jeder Struktur einen Längenparameter mit und unterscheiden anhand der Länge, um welche Struktur es sich handelt, also:

struct A {

unsigned Size; // sizeof(A)

...

};

struct B {

unsigned Size; // sizeof(B)

...

};

Wichtig ist dabei, dass der Längenparameter immer an erster Stelle steht und die verschiedenen Strukturen auch tatsächlich eine unterschiedliche Größe haben, damit sie so überhaupt unterscheidbar sind.

Die Auswertung könnte dann in etwa so aussehen:

void foo(void* pData) {

unsigned size = 0;

struct A* pA;

struct B* pB;

if(pData != 0) {

size = *(unsigned*)pData;

if(size == sizeof(struct A)) {

pA = (struct A*)pData;

// ...

} else if(size == sizeof(struct B)) {

pB = (struct B*)pData;

//...

}

...

}

}

Microsoft verwendet diese Technik, um Strukturen zu unterscheiden, die sich im laufe der Zeit mal verändert haben und um einige Sachen erweitert wurden.

Gruß

Frobber

Bearbeitet von frobber

und die verschiedenen Strukturen auch tatsächlich eine unterschiedliche Größe haben, damit sie so überhaupt unterscheidbar sind.

Da man das aber nicht immer vorraussetzen kann, da erstens Datengrößen sich im späteren Verlauf unterscheiden können bzw. zweitens, die Größe der Primitives von Compiler zu Compiler variieren, würde ich das nur als suboptimale Lösung empfinden.

... da erstens Datengrößen sich im späteren Verlauf unterscheiden können ...

Du denkst dabei wahrscheinlich an eine Änderung der Daten durch dynamisches allokieren mittels 'new' oder 'malloc'. Dadurch ändert sich aber nichts an der größe der Struktur an sich, sondern lediglich quasi semantisch der Inhalt der Struktur. Dem 'sizeof(...)' Operator ist es egal.

Bsp.:

struct A {

  unsigned Size; // sizeof(A)

  char* pData;  // dynamisch allokierter Speicher

  ...

};


void foo() {

  struct A a_dummy; // instance of A

  unsigned i = sizeof(a_dummy); // i ist 8


  a_dummy.pData = (char*)malloc(10);

  i = sizeof(a_dummy); // ist ist immernoch 8

}

Die einmal durch Deklaration definierte Größe einer Struktur kann sich zur Laufzeit nicht ändern.

zweitens, die Größe der Primitives von Compiler zu Compiler variieren

In dem Punkt geb ich dir teilweise Recht, aber das ist eher eine Frage der Plattform, als eine des Compilers. Primitive Datentypen werden zwischen verschiedenen Compilern auf der selben Plattform (im Sinne von Linux, Windows, ARM) in der Regel gleich behandelt.

Interessanter ist da eher die Frage nach dem Packing der Strukturen. Da kann man schnell auf Nase fallen.

...würde ich das nur als suboptimale Lösung empfinden

Ja ich würde auch eher deine Lösung wählen, wenn ich nicht genau weiß was mit den Strukturen im Laufe der Entwicklung noch so passiert.

Du denkst dabei wahrscheinlich an eine Änderung der Daten durch dynamisches allokieren mittels 'new' oder 'malloc'.

Eher nicht, ich dachte vielmehr an:

Ja ich würde auch eher deine Lösung wählen, wenn ich nicht genau weiß was mit den Strukturen im Laufe der Entwicklung noch so passiert.

Im Sinne von Remodellierung. Dann ist schwups mal Struktur C so groß wie Struktur A, weil auf einmal noch ein Charpointer Member der Struktur ist.

gut na dann sag ich doch mal danke ^^ ich überleg mir mal ob ich es so in das projekt einbinden kann ;)

insgesammt war es eh eher nur eine optionale idee, damit es weniger fehler auftauchen könnten wenn es benutzt werden würde.

darum nochmal ein danke an alle ;)

Archiv

Dieses Thema wurde archiviert und kann nicht mehr beantwortet werden.

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.