W C nie ma „wywołania zwrotnego” - nie więcej niż jakakolwiek inna generyczna koncepcja programowania.
Są zaimplementowane za pomocą wskaźników funkcji. Oto przykład:
void populate_array(int *array, size_t arraySize, int (*getNextValue)(void))
{
for (size_t i=0; i<arraySize; i++)
array[i] = getNextValue();
}
int getNextRandomValue(void)
{
return rand();
}
int main(void)
{
int myarray[10];
populate_array(myarray, 10, getNextRandomValue);
...
}
W tym przypadku populate_array
funkcja przyjmuje wskaźnik funkcji jako trzeci parametr i wywołuje go w celu pobrania wartości do zapełnienia tablicy. Napisaliśmy wywołanie zwrotne getNextRandomValue
, które zwraca losową wartość i przekazaliśmy do niej wskaźnik populate_array
. populate_array
wywoła naszą funkcję zwrotną 10 razy i przypisze zwrócone wartości do elementów w podanej tablicy.
Oto przykład wywołań zwrotnych w C.
Powiedzmy, że chcesz napisać kod, który umożliwi rejestrowanie wywołań zwrotnych w przypadku wystąpienia jakiegoś zdarzenia.
Najpierw zdefiniuj typ funkcji używanej do wywołania zwrotnego:
Teraz zdefiniuj funkcję, która zostanie użyta do zarejestrowania wywołania zwrotnego:
Tak wyglądałby kod rejestrujący wywołanie zwrotne:
We wnętrzu modułu wywołującego zdarzenia callback może być przechowywany w strukturze, która wygląda mniej więcej tak:
Tak wygląda kod, który wykonuje wywołanie zwrotne.
źródło
libsrtp
nie daje żadnych ostrzeżeń. Zakładam więc, że kiedy taki typ pojawia się jako argument funkcji, to wymaga się `` rozpadu '' na wskaźnik-do-funkcji, tak jak tablice rozpadają się na wskaźniki do ich pierwszych elementów, więc to samo dzieje się na końcu tak czy inaczej. To jest ciekawe, jednak, że dyskusje takich typedefs znalazłem nawet nie spojrzał na ten aspekt, a skupić się na deklarując prototypy lub wskaźniki z nimProsty program oddzwaniania. Mam nadzieję, że to odpowiada na twoje pytanie.
źródło
Funkcja zwrotna w C jest odpowiednikiem parametru / zmiennej funkcji przypisanej do użycia w innej funkcji. Przykład Wiki
W poniższym kodzie
Funkcja (* numberSource) wewnątrz wywołania funkcji PrintTwoNumbers jest funkcją "oddzwaniania" / wykonywania z wnętrza PrintTwoNumbers, zgodnie z kodem w trakcie jego działania.
Więc jeśli masz coś w rodzaju funkcji pthread, możesz przypisać inną funkcję do uruchamiania wewnątrz pętli z jej wystąpienia.
źródło
Funkcja zwrotna w C to funkcja udostępniana innej funkcji w celu „oddzwonienia” w pewnym momencie, gdy inna funkcja wykonuje swoje zadanie.
Istnieją dwa sposoby wykorzystania wywołania zwrotnego : synchroniczny i asynchroniczny callback zwrotna. Synchroniczne wywołanie zwrotne jest dostarczane do innej funkcji, która wykona jakieś zadanie, a następnie wróci do dzwoniącego po zakończeniu zadania. Asynchroniczne wywołanie zwrotne jest dostarczane do innej funkcji, która ma rozpocząć zadanie, a następnie wrócić do obiektu wywołującego z zadaniem prawdopodobnie nie zakończonym.
Synchroniczne wywołanie zwrotne jest zwykle używane w celu zapewnienia delegata innej funkcji, do której druga funkcja deleguje pewien krok zadania. Klasycznymi przykładami tej delegacji są funkcje
bsearch()
iqsort()
biblioteka standardowa C. Obie te funkcje przyjmują wywołanie zwrotne, które jest używane podczas zadania, które funkcja zapewnia, tak że typ wyszukiwanych danych, w przypadkubsearch()
lub sortowania, w przypadkuqsort()
, nie musi być znany funkcji będącej używany.Na przykład tutaj jest mały przykładowy program
bsearch()
wykorzystujący różne funkcje porównawcze, synchroniczne wywołania zwrotne. Umożliwiając nam delegowanie porównania danych do funkcji zwrotnej,bsearch()
funkcja ta pozwala nam zdecydować w czasie wykonywania, jakiego rodzaju porównania chcemy użyć. Jest to synchroniczne, ponieważ gdybsearch()
funkcja zwraca, zadanie jest zakończone.Asynchroniczne wywołanie zwrotne różni się tym, że gdy wywoływana funkcja, której dostarczamy, powraca, zadanie może nie zostać ukończone. Ten typ wywołania zwrotnego jest często używany w przypadku asynchronicznych operacji we / wy, w których operacja we / wy jest uruchamiana, a po jej zakończeniu wywoływana jest funkcja zwrotna.
W poniższym programie tworzymy gniazdo do nasłuchiwania żądań połączenia TCP, a po odebraniu żądania funkcja nasłuchująca wywołuje dostarczoną funkcję zwrotną. Tę prostą aplikację można uruchomić, uruchamiając ją w jednym oknie, podczas gdy
telnet
narzędzie lub przeglądarka internetowa próbuje połączyć się w innym oknie.Podniosłem większość kodu WinSock z przykładu dostarczonego przez Microsoft z
accept()
funkcją pod adresem https://msdn.microsoft.com/en-us/library/windows/desktop/ms737526(v=vs.85).aspxAplikacja ta rozpoczyna się
listen()
na lokalnym komputerze, 127.0.0.1, za pomocą portu 8282, więc można użyć jednejtelnet 127.0.0.1 8282
lubhttp://127.0.0.1:8282/
.Ta przykładowa aplikacja została utworzona jako aplikacja konsolowa w programie Visual Studio 2017 Community Edition i korzysta z wersji gniazd Microsoft WinSock. W przypadku aplikacji dla systemu Linux funkcje WinSock musiałyby zostać zastąpione alternatywami dla systemu Linux, a biblioteka wątków systemu Windows byłaby używana
pthreads
zamiast tego.źródło
Wywołania zwrotne w C są zwykle implementowane przy użyciu wskaźników funkcji i powiązanego wskaźnika danych. Przekazujesz swoją funkcję
on_event()
i wskaźniki danych do funkcji strukturywatch_events()
(na przykład). Gdy ma miejsce zdarzenie, wywoływana jest funkcja z Twoimi danymi i niektórymi danymi specyficznymi dla zdarzenia.Callbacki są również używane w programowaniu GUI. GTK + poradnik ma sekcję Nicei na teorii sygnałów i wywołania zwrotne .
źródło
Ten artykuł na Wikipedii ma przykład w C.
Dobrym przykładem jest to, że nowe moduły napisane w celu rozszerzenia serwera WWW Apache rejestrują się o główny proces Apache, przekazując im wskaźniki funkcji, aby te funkcje były wywoływane z powrotem w celu przetwarzania żądań stron internetowych.
źródło
Zwykle można to zrobić za pomocą wskaźnika funkcji, czyli specjalnej zmiennej, która wskazuje lokalizację funkcji w pamięci. Możesz następnie użyć tego do wywołania funkcji z określonymi argumentami. Więc prawdopodobnie będzie funkcja, która ustawia funkcję zwrotną. To zaakceptuje wskaźnik funkcji, a następnie zapisze ten adres gdzieś, gdzie może być używany. Następnie, gdy określone zdarzenie zostanie wyzwolone, wywoła tę funkcję.
źródło
O wiele łatwiej jest zrozumieć pomysł na przykładzie. To, co dotychczas powiedziano o funkcji wywołania zwrotnego w C, to świetne odpowiedzi, ale prawdopodobnie największą zaletą korzystania z tej funkcji jest utrzymanie kodu w czystości i porządku.
Przykład
Poniższy kod C implementuje szybkie sortowanie. Najciekawszą linią w poniższym kodzie jest ta, w której możemy zobaczyć funkcję callback w akcji:
Porównanie_s2b to nazwa funkcji, której qsort () używa do wywołania funkcji. Dzięki temu qsort () jest uporządkowana (stąd łatwiejsza w utrzymaniu). Po prostu wywołujesz funkcję po nazwie z wnętrza innej funkcji (oczywiście przynajmniej deklaracja prototypu funkcji musi być wcześniejsza, zanim będzie można ją wywołać z innej funkcji).
Kompletny kod
źródło