Forum: Mikrocontroller und Digitale Elektronik Für C Profis: Funktionszeiger


von Hakan (Gast)


Lesenswert?

Hallo Zusammen
Wie kann ich in C einen Funktionszeiger an eine Funktion übergeben und 
in der Funktion dann die Zeiger-Funktion aufrufen?

z.B.

Die API-Funktion Get_Socket() erwartet als parameter einen 
Funktionszeiger listner:

bool Get_Socket(int type, int(*listner)(int socket));

Ich möchte diese API-Funktion nicht direkt aufrufen sondern durch meine 
selbsterstellte übergeordnete Funktion aufrufen.

bool My_Get_Sockt(int type, int (*listner)(char socket))
{
  return Get_Socket(type,(*listner)(socket));
}

Hat aber leider nicht funktioniert. Was mache ich falsh?
Danke im Voraus.

von (prx) A. K. (prx)


Lesenswert?

return Get_Socket(type, listner);

von Hakan (Gast)


Lesenswert?

geht nicht! trotzdem Danke

von (prx) A. K. (prx)


Lesenswert?

Ist socket nun int oder char?

von Hakan (Gast)


Lesenswert?

sorry! socket ist int

von Karl H. (kbuchegg)


Lesenswert?

Hakan schrieb:
> geht nicht! trotzdem Danke

doch das geht.

Dann hast du eben noch einen anderen Fehler.
Woraus wir lernen: Codeausschnitte zu posten ist meistens eine ganz 
schlechte Idee. Poste so viel wie möglich, im besten Falle alles.

von Karl H. (kbuchegg)


Lesenswert?

Hakan schrieb:
> sorry! socket ist int

Warum sagt dann deine Funktion

bool My_Get_Sockt(int type, int (*listner)(char socket))

dass die Funktion, die sich hinter dem Pointer verbirgt einen char haben 
will?



Grundsätzlich:
Wenn man mit Funktionspointern arbeitet, ist man IMMER gut beraten, sich 
für den Typ einer Funktion einen Typedef zu machen.
1
// Get_Socket will einen Funktionszeiger auf eine Funktion, die
2
// einen int als Argument übernimmt und einen int als Returnwert liefert
3
//
4
// ALso dieser Datentyp, den wir mal LstnFnct nennen:
5
typedef int (*LstnFnct) ( int Socket );
6
7
bool My_Get_Sockt( int type, LstnFnct listner )
8
{
9
  return Get_Socket( type, listner );
10
}

von Hakan (Gast)


Lesenswert?

Hallo Karl,

Danke für den Rat hat aber nicht geholfen.

von Andreas B. (andreas_b77)


Lesenswert?

Hakan schrieb:
> bool My_Get_Sockt(int type, int (*listner)(char socket))
> {
>   return Get_Socket(type,(*listner)(socket));
> }

So ruft man eine Funktion über einen Zeiger auf, das Dereferenzieren 
könnte man sich aber auch sparen. Aber da kommt dann ein int raus, 
Get_Socket will aber einen Funktionszeiger, zweitens ist socket hier 
nicht definiert, kann listner also nicht als Parameter übergeben werden. 
Das soll also bestimmt Get_Socket(type, listner) heißen, also der 
Funktionszeiger übergeben werden.


Was ganz anderes: Das soll wohl auch "listener" heißen, falls es 
abgeleitet von "listen" ist.

von Simon B. (nomis)


Lesenswert?

Hakan schrieb:
> Danke für den Rat hat aber nicht geholfen.

Du machst das mit Absicht, oder? Meine arme Tischkante...

[x] Poste die Fehlermeldung
[x] Poste den tatsächlichen Code

Viele Grüße,
        Simon

von Klaus W. (mfgkw)


Lesenswert?

naja, eigentlich ist es schon halbwegs klar - vermute ich.

Ein Zeiger int(*listner)(int socket) ist nicht kompatibel zu einem 
int(*listner)(char socket).

Man muß sich halt entscheiden können.

von Hakan (Gast)


Lesenswert?

@Andreas:
Ja: listener anstatt Listner (Englisch halt: ist aber hier nicht 
wichtig)

mit return Get_Socket(type,(*listner)(socket));
bekomme ich die Fehlermeldungen:
tcp_ip.cpp(170): error:  #254: type name is not allowed
tcp_ip.cpp(170): error:  #18: expected a ")"

:-(

Danke Trotzdem.

von Andreas B. (andreas_b77)


Lesenswert?

Hakan schrieb:
> mit return Get_Socket(type,(*listner)(socket));
> bekomme ich die Fehlermeldungen:

Und was kommt nu mit Get_Socket(type, listner)? Einzig eine Warnung 
wegen nicht ganz kompatibler Zeigertypen (wegen char statt int) dürfte 
kommen.

von Hakan (Gast)


Lesenswert?

Hallo Leute,
Danke Euch für die Mühe.
ich versuche mal morgen das ganze in einer main() zu packen sodass jeder
das testen kann.
Gruß

von Karl H. (kbuchegg)


Lesenswert?

Hakan schrieb:
> @Andreas:
> Ja: listener anstatt Listner (Englisch halt: ist aber hier nicht
> wichtig)
>
> mit return Get_Socket(type,(*listner)(socket));
> bekomme ich die Fehlermeldungen:
> tcp_ip.cpp(170): error:  #254: type name is not allowed
> tcp_ip.cpp(170): error:  #18: expected a ")"
>
> :-(
>
> Danke Trotzdem.


sag mal. Liest du auch was man dir schreibt


    return Get_Socket(type, listner);


Der Pointer heisst listener. Und der wird an die nächste Funktion 
weitergegeben. Aus, Ende. Mehr braucht es nicht.

Auch ein Funktionszeiger ist einfach nur ein Zeiger.

von Simon K. (simon) Benutzerseite


Lesenswert?

Das sieht AFAIK danach aus, als hättest du komische Zeichen in deiner .c 
Datei.

von Simon B. (nomis)


Lesenswert?

Hakan schrieb:
> mit return Get_Socket(type,(*listner)(socket));

Das ist nicht das, was dir in der allerallerersten Antwort auf deine 
Frage als Lösung vorgeschlagen wurde.

Viele Grüße,
        Simon

von Simon B. (nomis)


Lesenswert?

Simon K. schrieb:
> Das sieht AFAIK danach aus, als hättest du komische Zeichen in deiner .c
> Datei.

Genau. Runde Klammern und Sterne an stellen wo sie nicht hingehören...

Viele Grüße,
        Simon

von Hakan (Gast)


Lesenswert?

Es liegt definitv nicht an den Datentyp des Sockets: Das war ein 
Tippfehler von mir hier beim posten.(int statt char :siehe oben)

noch mal:

Die API-Funktion Get_Socket() erwartet als parameter einen
Funktionszeiger listner:

bool Get_Socket(int type, int(*listner)(int socket));

Ich möchte diese API-Funktion nicht direkt aufrufen sondern durch meine
selbsterstellte übergeordnete Funktion aufrufen.

bool My_Get_Sockt(int type, int (*listner)(int socket))
{
  return Get_Socket(type,(*listner)(socket));
}

von Karl H. (kbuchegg)


Lesenswert?

Hakan schrieb:
> Es liegt definitv nicht an den Datentyp des Sockets: Das war ein
> Tippfehler von mir hier beim posten.(int statt char :siehe oben)
>
> noch mal:
>
> Die API-Funktion Get_Socket() erwartet als parameter einen
> Funktionszeiger listner:
>
> bool Get_Socket(int type, int(*listner)(int socket));
>
> Ich möchte diese API-Funktion nicht direkt aufrufen sondern durch meine
> selbsterstellte übergeordnete Funktion aufrufen.
>
> bool My_Get_Sockt(int type, int (*listner)(int socket))
> {
>   return Get_Socket(type,(*listner)(socket));
> }

Grrrrrr

   return Get_Socket(type, listner);

von (prx) A. K. (prx)


Lesenswert?

Gibs auf. Gegen diese Sturheit kommst du nicht an. ;-)

von besserwisser (Gast)


Lesenswert?

A. K. schrieb:
> Gegen diese Sturheit kommst du nicht an. ;-)

Karl Heinz kriegt jeden Anfänger(fehler) klein! <-- Das ist ein 
Kompliment...

von Karl H. (kbuchegg)


Lesenswert?

A. K. schrieb:
> Gibs auf. Gegen diese Sturheit kommst du nicht an. ;-)

Wenn er nicht sooooo stur wäre.

Er tauscht das aus, kriegt eine neue Fehlermeldung und denkt sich:
Hops, das kann es dann wohl nicht gewesen sein, alles retour.

Das die Korrektur des einen Fehlers den nächsten Fehler zum Vorschein 
bringt, dürfte ihm noch nicht gedämmert haben.

von Hakan (Gast)


Lesenswert?

Es klemmt beim Aufruf des Funktionszeiger bei func3.
[C++ Fehler] Unit1.c(28): E2121 ) fehlt beim Funktionsaufruf
Hat jemand eine Lösung?
Danke
Hakan


#include <conio.h>
#include <stdio.h>

int (*listener)(int a,int b);

int func1(int a,int b);
int func2(int a,int b);
int func3( int c,int (*fx)(int a,int b));

int main(int argc, char* argv[])
{
  listener = func1;

  printf("listener = func1 Ergenbis=%d\n",(*listener)(2,3));

  listener = func2;

  printf("listener = func2 Ergenbis=%d\n",(*listener)(3,1));

  printf("func3  Ergenbis=%d\n",func3(10,listener);
  //!!!!!!!!!!!!!!!!!! hier klemmt's bei func3(10,listener)


  getche();
  return 0;
}

int func1(int a,int b)
{
  return a+b;
}

int func2(int a,int b)
{
  return a-b;
}

int func3( int c,int (*f1)(int a,int b))
{
  return  (*f1)(c,c);
}

von Stefan E. (sternst)


Lesenswert?

Hakan schrieb:
> printf("func3  Ergenbis=%d\n",func3(10,listener);
>   //!!!!!!!!!!!!!!!!!! hier klemmt's bei func3(10,listener)

Und was da klemmt ist exakt das, was in der Fehlermeldung steht:
> ) fehlt beim Funktionsaufruf

von Hakan (Gast)


Lesenswert?

Stefan: was hättest den geschrieben anstatt:
printf("func3  Ergenbis=%d\n",func3(10,listener);?

von Karl H. (kbuchegg)


Lesenswert?

Zähl doch mal die Klammern!

 printf("func3  Ergenbis=%d\n",func3(10,listener);
       ^
       |  hier geht eine Klammer auf


 printf("func3  Ergenbis=%d\n",func3(10,listener);
                                    ^
                                    | hier geht noch eine Klammer auf


 printf("func3  Ergenbis=%d\n",func3(10,listener);
                                                ^
                                                | 1 Klammer zu


2 Klammern auf, 1 Klammer zu.

Na, klingelts?

von Hakan (Gast)


Lesenswert?

Danke dir sehr. Ich glaub ich muss die Brille wechseln.

von Karl H. (kbuchegg)


Lesenswert?

Hakan schrieb:
> Danke dir sehr. Ich glaub ich muss die Brille wechseln.

Eher aufhören, alles in einer Wurscht ohne Leerzeichen zu schreiben.

von Klaus W. (mfgkw)


Lesenswert?

... und den richtigen Editor nehmen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.