Hallo,
ich habe ein Problem mit dem Casten von void-Pointern, die eigentlich auf Strukturen zeigen. Am Besten schildere ich mal kurz den Zusammenhang...
Es gibt eine Struktur:
typedef struct{ char *pName; char *pFirstName; char *pNumber; } tRecord;
Die Struktur stellt einen Datensatz eines Telefonverzeichnisses dar. �ber eine verkettete Liste werden die Datens�tze verwaltet und bereits bei der Eingabe alphabetisch geordnet. Der Listen- modul stellt daf�r folgende Funktion bereit:
void* addItemToList (tList* pList, void * pItem, int(*fcmp)(void*pItList,void*pItNew));
F�r int(*fcmp) wird ein Pointer auf eine Vergleichsfunktion er- wartet, die die entsprechende Syntax hat. Da die Liste keine Ahnung vom Typ der verwalteten Daten haben muss, werden dabei lediglich void-Pointer �bergeben. Mein Problem ist nun folgendes: Von addItemToList wird f�r jedes bereits in der Liste vorhandene Element vom Typ tRecord die Vergleichsfunktion RecordCompare aufgerufen.
int RecordCompare(void *pItList, void *pItNew) { return strcmp((tRecord*)(pItList->pName),(tRecord*)(pItNew->pName)); }
RecordCompare erh�lt also f�r seine beiden Parameter jeweils einen Pointer auf eine Struktur tRecord, die es vorl�ufig noch als void* betrachtet. Wie aus dem Quelltextschnipsel zu er- sehen ist, soll nichts weiter gemacht werden, als zwei Strings zu vergleichen. Die beiden void-Pointer habe ich also als tRecord gecastet und wollte so an die Zeichenketten pName herankommen. Aber der GCC gibt mir folgende Meldungen:
phon.c: In function `RecordCompare': phon.c:22: warning: dereferencing `void *' pointer phon.c:22: request for member `pName' in something not a structure or union phon.c:22: warning: dereferencing `void *' pointer phon.c:22: request for member `pName' in something not a structure or union make: *** [all] Error 1
Anscheinend habe ich mit dem Casting irgend etwas falsch ge- macht, der GCC erkennt die Struktur nicht als solche. Probiert habe ich bis jetzt alle m�glichen Klammerungen, komme aber nicht mehr weiter. Muss ich dem GCC zus�tzlich noch verklickern, dass "pName" ein char* ist oder wo muss ich ansetzen?
Viele Gr��e, Matthias
Hi Matthias,
On Tue, Feb 26, 2002 at 15:59:53 +0000, Matthias Petermann wrote:
int RecordCompare(void *pItList, void *pItNew) { return strcmp((tRecord*)(pItList->pName),(tRecord*)(pItNew->pName)); }
[...]
Anscheinend habe ich mit dem Casting irgend etwas falsch ge- macht, der GCC erkennt die Struktur nicht als solche. Probiert habe
<SCNR> Wende Dich doch einfach an eine Casting-Agentur :) </SCNR>
Sieht so aus, als haettest Du falsch geklammert. Mit return strcmp((tRecord*)(pItList)->pName, (tRecord*)(pItNew)->pName); sollte es klappen. Es muss zuerst der void-Pointer pItList auf einen typisierten Pointer gecastet werden, damit "->pName" ueberhaupt erlaubt ist.
Disclaimer: Alles ungetestet und nur kurz druebergeschaut. You may flame now.
bye, Chris
Hallo Christian,
vielen vielen Dank f�r Deine Antwort!
On Tue, Feb 26, 2002 at 04:29:01PM +0100, Christian Perle wrote:
Sieht so aus, als haettest Du falsch geklammert. Mit return strcmp((tRecord*)(pItList)->pName, (tRecord*)(pItNew)->pName);
Deine Erkl�rung dazu, dass das ->pName" �berhaupt erst erlaubt ist, wenn der Typ des Pointers klar ist, hat mir die Erleuchtung gebracht Ich habs jetzt so gemacht:
return strcmp(((tRecord*)pItList)->pName,((tRecord*)pItNew)->pName);
Die zus�tzliche Klammer um das (tRecord*)pItList fehlt bei Deinem Beispiel, aber wie schon gesagt, die Erkl�rung hat's gebracht :)
Vielen Dank nochmal,
Matthias
lug-dd@mailman.schlittermann.de