www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ptr-to-funct typ error


Autor: Bernd Schuster (mms)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
void funct (unsigned char *pchar)        

struct Struct2 { 

    void  *ptr; 
    //... 
}; 

typedef struct { 

    struct Struct2   *p 
    //... 
}Struct1; 

Struct1 *pstruct; 
unsigned char *pchar;   


pstruct->p->ptr = funct(pchar); 

Bei der letzten Zeile bekomme ich die Fehlermeldung: "expression must 
have (pointer-to-) function type... was muss ich anders schreiben, damit 
diese nicht mehr auftritt?

gruß
bernd

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich verstehe in deinem Codeschnippsel nicht, was du machen willst. Was 
IMHO hapert ist, deine fehlende Definition des Platzes worauf die vielen 
Zeiger zeigen...

In folgendem Democode ist das nachgeholt und es tritt auch kein Fehler 
beim Übersetzen auf.

Unklar ist mir allerdings, was du in pstruct->p->ptr eintragen willst, 
func(pchar) ist unsinnig, weil diese Funktion ja keinen Rückgabewert 
hat.

void funct (unsigned char *pchar);

struct Struct2 
{ 
  void  * ptr; 
}; 

typedef struct 
{ 
  struct Struct2 * p;
} Struct1; 

Struct1 * pstruct; 
unsigned char * pchar;   

void funct (unsigned char *pchar)
{
}


int main(void)
{
  // bevor was eingetragen werden kann
  // Platz anlegen, WO das eingetragen werden kann
  Struct1 s1;
  struct Struct2 s2;

  // korrekt verlinken
  pstruct = &s1;
  pstruct->p = &s2;

  // Erst jetzt darf gefahrlos eingetragen werden!

  // Option 1 - Adresse der Funktion in ptr eintragen
  pstruct->p->ptr = funct;

  // Option 2 - Argument der Funktion in ptr eintragen
  pstruct->p->ptr = pchar;

  // Option 3 - Rückgabewert der Funktion in ptr eintragen 
  // (dem widerspricht deine void func... Deklaration)
  // pstruct->p->ptr = funct(pchar);

  return 42;
}


Autor: Bernd Schuster (mms)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
funct stellt eine normale funktion dar.... (lediglich rückgabewert hat 
sich geändert)
short funct (unsigned char *pchar);

global hab ich die beiden structs definiert (im header-file)
struct Struct2 
{ 
  void  * ptr; 
}; 

typedef struct 
{ 
  struct Struct2 * p;
} Struct1; 

in der main-function mache ich dann u.a. folgendes
Struct1 *pstruct; 
  unsigned char *pchar; 

  (short) (*pstruct->p->ptr)(unsigned char *pchar) = funct; 
  if((pstruct->p->ptr)(pchar) != 0); 

zuerst möchte ich gern einen funktionspointer ptr auf die funktion funct 
erstellen. Anschließend möchte ich gern die funktion funct aufrufen mit 
dem Übergabewert pchar - der Return-Wert wird in der if-Anweisung 
ausgeführt.

Hier befinden sich jedoch einige Fehler.

gruß
bernd

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bernd Schuster wrote:
> funct stellt eine normale funktion dar.... (lediglich rückgabewert hat
> sich geändert)
>
> short funct (unsigned char *pchar);

Dann macht die Zuweisung an ptr (ist void *) auch keinen Sinn. Oder 
willst du dass der short Rückgabewert als void * in der Struktur 
gespeichert wird?

> global hab ich die beiden structs definiert (im header-file)
>
> struct Struct2
> {
>   void  * ptr;
> };
>
> typedef struct
> {
>   struct Struct2 * p;
> } Struct1;

Das ist keine Definition sondern es sind zwei Deklarationen.

Du deklarierst nur zwei besondere Datentypen deines Programmes. Zu einer 
Definition gehört, dass Platz eingerichtet wird.

> in der main-function mache ich dann u.a. folgendes
>
> Struct1 *pstruct;
> unsigned char *pchar;
>
> (short) (*pstruct->p->ptr)(unsigned char *pchar) = funct;

Das ist kritisch, weil du in den ersten Beiden Zeilen nur zwei Pointer 
definierst, die sind aber auf NULL initialisiert. D.h. sie zeigen nicht 
auf eine gültige Struktur. Du musst zuerst die Strukturen vom Platz her 
definieren und dann die gier definierten Pointer darauf richten. Dann 
erst darfst du den Pointern etwas zuweisen (oder etwas auslesen).

> zuerst möchte ich gern einen funktionspointer ptr auf die funktion funct
> erstellen.

Also die Option 1 oben.

> Anschließend möchte ich gern die funktion funct aufrufen mit
> dem Übergabewert pchar - der Return-Wert wird in der if-Anweisung
> ausgeführt.
>
>   if((pstruct->p->ptr)(pchar) != 0);
>
> Hier befinden sich jedoch einige Fehler.

So würde es gehen:

short funct (unsigned char *pchar);

struct Struct2 
{ 
  short (*ptr)(unsigned char *); 
}; 

typedef struct 
{ 
  struct Struct2 * p;
} Struct1; 

Struct1 * pstruct; 
unsigned char * pchar;   

short funct (unsigned char *pchar)
{
  return -1;
}


int main(void)
{
  // bevor was eingetragen werden kann
  // Platz anlegen, WO das eingetragen werden kann
  Struct1 s1;
  struct Struct2 s2;

  // korrekt verlinken
  pstruct = &s1;
  pstruct->p = &s2;

  // Erst jetzt darf gefahrlos eingetragen werden!

  // Option 1 - Adresse der Funktion in ptr eintragen
  pstruct->p->ptr = funct;

  if((pstruct->p->ptr)(pchar) != 0)
    return 23;
  else
    return 42;
}


Aber daran denken, dass der Zeiger pchar noch nicht initalisiert ist. 
funct darf daraus nichts herauslesen oder hineinschreiben!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.