Kann eine statische Funktion über einen Funktionszeiger in C aufgerufen werden?

Lesezeit: 3 Minuten

Ich glaube, dass eine statische Funktion in einer Quelldatei nicht direkt von außerhalb der Datei aufgerufen werden kann. Wenn ich es jedoch irgendwie schaffe, einen Zeiger auf diese Funktion in eine andere Datei zu bekommen, kann ich diese Funktion dann von dieser Datei aus aufrufen. Wenn ja, gibt es ein Szenario, in dem wir diesen Weg einschlagen möchten, anstatt die Funktion einfach nicht statisch zu machen?

  • Ich frage mich, was das Verhalten ist, wenn Sie dies mit dem mischen inline Schlüsselwort und/oder proprietäre Compiler-Direktiven, die immer eine Funktion einbetten würden.

    – mpontillo

    25. Januar 2014 um 2:18 Uhr


  • @mpontillo Ich glaube das auch wenn die Funktion als markiert ist inline Die Adresse wird jedoch in einem Funktionszeiger verwendet, der Compiler würde den Hauptteil in der Binärdatei generieren und ihn gleichzeitig in andere Funktionen im selben Modul einfügen.

    – Ajay Brahmakshatriya

    9. Mai 2017 um 4:58 Uhr

Ja, Sie können statische Funktionen exportieren, indem Sie ihnen Zeiger übergeben. Dies ist ein gängiges Mittel zur Umsetzung der Fabrikmuster in C, wo Sie die Implementierungen einer ganzen Reihe von Funktionen vor den Modulen verbergen können, die sie verwenden, und eine haben FuncPtr_t GetFunction( enum whichFunctionIWant) die sie an die Verbraucher aushändigt. So viele dynamische Verlinkung Implementierungen funktionieren.

Wenn ich es jedoch irgendwie schaffe, einen Zeiger auf diese Funktion in eine andere Datei zu bekommen, kann ich diese Funktion dann von dieser Datei aus aufrufen.

Ja, es ist durchaus möglich. Die Funktion ist für den Linker nicht sichtbar, aber in der ausführbaren Datei vorhanden. Sie können jederzeit zu seiner Adresse springen.

Bei Szenarien bin ich mir aber nicht sicher. Vielleicht möchten Sie, dass andere Ihre Funktion nur aufrufen nach Sie haben eine andere Funktion aufgerufen (natürlich nicht statisch). Du hast sie also erhalten es, und dann können sie es anrufen.

Wie der andere erwähnt, können Sie es tun. Ein Beispiel dafür, warum Sie das vielleicht möchten, ist eine Art “Treiber”. Sie könnten eine Struktur zurückgeben, die die Funktionen zum Öffnen, Schließen, Lesen und Schreiben enthält, ohne die eigentlichen Funktionen öffentlich zugänglich machen zu müssen.

  • Verhalten wie C++-Klassenmitgliedsfunktion. oops

    – Benutzer26742873

    17. August 2020 um 14:49 Uhr


Ja, du kannst. Wenn Sie eine Funktion aufrufen müssen, die einen Zeiger auf eine Funktion als Rückruf erwartet, können Sie static verwenden, damit das Funktionssymbol den globalen Namespace nicht verschmutzt und keine Linkerkonflikte verursacht. Das am häufigsten verwendete Beispiel ist wahrscheinlich qsort:

struct Data { ... };

static int compareData(const void* a, const void* b) { /* cast to Data and compare */ }

...
qsort(array, count, sizeof(Data), &compareData);

Ja, eine nicht statische Funktion in Ihrer Datei kann einen Zeiger auf eine statische Funktion an eine beliebige Stelle zurückgeben.

Benutzer-Avatar
AusCBloke

Ja, das kannst du, du könntest es jederzeit selbst ausprobieren und herausfinden:

Datei1.c

#include <stdio.h>

void call_hello(void (*fptr)(void));

static void hello(void) {
   puts("hello");
}

int main(void)
{
   void (*fptr)(void) = hello;

   call_hello(fptr);

   return 0;
}

Datei2.c

void call_hello(void (*fptr)(void))
{
   fptr();
}

Benutzer-Avatar
Basile Starynkevitch

Oft ist es sinnvoll, eine kleine statische Funktion als Arbeitsfunktion für eine andere zu definieren. Schau dir die Norm an qsort zum Beispiel: Es erwartet eine Vergleichsfunktion, und sehr oft ist es besser, diese Vergleichsfunktion statisch zu machen (z. B. weil sie an anderer Stelle nicht nützlich ist, und weil qsort möchte, dass es eine unschöne Signatur hat).

1385680cookie-checkKann eine statische Funktion über einen Funktionszeiger in C aufgerufen werden?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy