Kurz gesagt: Ja, Sie statische Methoden über Zeiger zugreifen können.
Um dies zu verstehen, ist es wahrscheinlich am besten, ein wenig mehr zu verstehen, was unter der Haube des Compilers vor sich geht.
Aus Gründen der Übersichtlichkeit wird ein kompiliertes Programm in Maschinencode geschrieben. Es gibt zusätzliche Informationen im kompilierten Programm für den "Programmlader", aber das Programm selbst ist nur eine Anweisung, die vom Prozessor ausgeführt werden muss.
Wenn Sie eine Funktion "foo()" in C aufrufen, übersetzt der C-Compiler dies in eine "CALL" -Prozessoroperation. Der CALL-Operation folgt im Code die Adresse foo (wörtlich eine Speicheradresse oder "Offset"). Beachten Sie, dass der Name ("foo") nicht verwendet wird, da es sich um eine Speicheradresse handelt. Beachten Sie auch, dass der Linker nicht über "foo" Bescheid wissen muss, damit dies funktioniert.
Beim Aufruf einer Funktion „bar()“ in C und die Funktion ist in einer anderen Übersetzungseinheit (eine andere C-Datei) der Compiler ein bisschen ein Problem hat, weil es nicht da, wo im Programm nicht kennt (wo in Speicher) ist die Funktion anzurufen. Das heißt, es weiß nicht, welche Adresse nach der CALL-Operation geschrieben werden soll. Wenn dies geschieht, schreibt es den Code, der Platz für die Adresse lässt, hinterlässt jedoch eine Notiz für den Linker. Die Notiz teilt dem Linker mit, "gib hier die Adresse der Leiste an". Der Linker korrigiert also das geschriebene Programm anhand der Speicheradresse. Dies dem Linker zu ermöglichen; Der Compiler schreibt eine Tabelle, die jeden Funktionsnamen und die jeweilige Adresse im Code enthält.
Also was macht statische? Dies teilt dem Compiler einfach mit, den Namen und die Adresse für die Funktion in der Tabelle nicht zu schreiben, die an den Linker übergeben wird. Die Funktion existiert immer noch in Code als eine Funktion, aber der Linker weiß nicht, wo es ist. Jeder Code innerhalb derselben Kompilierungseinheit weiß, wo die Funktion ist. Daher kann jede Funktion innerhalb derselben Kompilierungseinheit die Adresse der Funktion als einen Zeiger außerhalb der Kompilierungseinheit übergeben.
Der Code c zu verwenden, um einen Funktionszeiger zu passieren ist so etwas wie dieses:
file1.h
typedef void (* VoidFunctionPointer)();
extern VoidFunctionPointer somethingInteresting;
bar();
file1.c
#include "a.h"
VoidFunctionPointer somethingInteresting;
static void foo() {
// do something interesting;
}
void bar() {
// we know what foo is because we're in the same compilation unit
somethingInteresting = foo;
}
file2.c
#include "a.h"
int main(int argC, char ** argV) {
bar();
// we can call somethingInteresting as if it is a function no matter
// wether it's declared static in code or not
// this can be foo, just as long as we don't have to use the name "foo"
somethingInteresting();
}
In diesem Code file2 Im Endeffekt wird eine statische Funktion von Datei1 ausgeführt. Der Schlüssel ist, dass Datei2 niemals den Namen dieser Funktion benötigt, daher hat statisch keine Auswirkung auf Funktionszeiger.
ich empfehlen kann Microsofts Beschreibung des PE-Format (.EXE und .DLL) [hier] zu lesen:
http://msdn.microsoft.com/en-us/library/ms809762.aspx
Wenn Sie auf die Funktion von anderen Kompilierungseinheiten zugreifen möchten, warum machen Sie sie dann "statisch"? – Jon
@Jon: Sie können einen Rückruf als statisch deklarieren (niemand kann die Funktion durch seinen Bezeichner aufrufen) und seinen Zeiger an eine Setup-Funktion senden, um auf ein Ereignis zu reagieren. Sie erzwingen, dass es eine Callback-Funktion ist und nicht wie eine reguläre Callback-Funktion. – Gauthier
@Gauthier: In diesem Fall müssen Sie nichts mehr tun, als einfach die Adresse an die Angerufenen übergeben: 'takes_callback (foo)' - ich sehe vorgeschlagen, dass Sie das schon. Das OP bittet (wie ich und andere Leute, die geantwortet haben) um einen global zugänglichen Funktionszeiger, was völlig sinnlos ist. Natürlich, die Menschen nicht die wörtliche Frage zu beantworten für moar rep nicht daran hindert * * ... –
Jon