Zum Inhalt springen

von void* gecastete struct* prüfen


Shamharoth

Empfohlene Beiträge

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 ^^

Link zu diesem Kommentar
Auf anderen Seiten teilen

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 ... ;)

Link zu diesem Kommentar
Auf anderen Seiten teilen

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:

Link zu diesem Kommentar
Auf anderen Seiten teilen

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?

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Link zu diesem Kommentar
Auf anderen Seiten teilen

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
Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Link zu diesem Kommentar
Auf anderen Seiten teilen

... 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.

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...