Não há "retorno de chamada" em C - não mais do que qualquer outro conceito de programação genérico.
Eles são implementados usando ponteiros de função. Aqui está um exemplo:
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);
...
}
Aqui, a populate_array
função pega um ponteiro de função como terceiro parâmetro e o chama para obter os valores para preencher a matriz. Escrevemos o retorno de chamada getNextRandomValue
, que retorna um valor aleatório, e passamos um ponteiro para ele populate_array
. populate_array
chamará nossa função de retorno de chamada 10 vezes e atribuirá os valores retornados aos elementos na matriz especificada.
Aqui está um exemplo de retornos de chamada em C.
Digamos que você queira escrever um código que permita o registro de retornos de chamada quando algum evento ocorrer.
Primeiro, defina o tipo de função usada para o retorno de chamada:
Agora, defina uma função que é usada para registrar um retorno de chamada:
Este é o código que registra um retorno de chamada:
Nas partes internas do distribuidor de eventos, o retorno de chamada pode ser armazenado em uma estrutura que se parece com isso:
É assim que o código executa um retorno de chamada.
fonte
libsrtp
apresentados em não dá avisos. Presumo, então, que quando esse tipo aparece como argumento de função, é necessário 'decair' para um ponteiro para função, assim como matrizes decaem para ponteiros para seus primeiros elementos, então a mesma coisa acontece no final de qualquer jeito. Ele é interessante, porém, que as discussões de tais typedefs que eu encontrei nem sequer olhar para este aspecto, sim focar declarar protótipos ou ponteiros com eleUm simples programa de retorno de chamada. Espero que ele responda sua pergunta.
fonte
Uma função de retorno de chamada em C é equivalente a um parâmetro / variável de função atribuído a ser usado em outra função. Exemplo da Wiki
No código abaixo,
A função (* numberSource) dentro da chamada de função PrintTwoNumbers é uma função para "retornar a chamada" / executar de dentro do PrintTwoNumbers conforme ditado pelo código enquanto é executado.
Portanto, se você tivesse algo como uma função pthread, poderia atribuir outra função para executar dentro do loop a partir da instanciação.
fonte
Um retorno de chamada em C é uma função fornecida a outra função para "retornar a chamada" em algum momento em que a outra função está executando sua tarefa.
Há duas maneiras pelas quais um retorno de chamada é usado : retorno de chamada síncrono e retorno de chamada assíncrono. Um retorno de chamada síncrono é fornecido para outra função que realiza alguma tarefa e depois retorna ao chamador com a tarefa concluída. Um retorno de chamada assíncrono é fornecido para outra função que iniciará uma tarefa e retornará ao chamador com a tarefa possivelmente não concluída.
Um retorno de chamada síncrono é normalmente usado para fornecer um delegado para outra função na qual a outra função delega alguma etapa da tarefa. Exemplos clássicos dessa delegação são as funções
bsearch()
eqsort()
da Biblioteca Padrão C. Ambas as funções recebem um retorno de chamada que é usado durante a tarefa que a função está fornecendo, para que o tipo de dados pesquisado, no caso debsearch()
, ou classificado, no caso deqsort()
, não precise ser conhecido pela função que está sendo usava.Por exemplo, aqui está um pequeno programa de amostra com o
bsearch()
uso de diferentes funções de comparação, retornos de chamada síncronos. Ao nos permitir delegar a comparação de dados em uma função de retorno de chamada, absearch()
função nos permite decidir em tempo de execução que tipo de comparação queremos usar. Isso é síncrono porque, quando absearch()
função retorna, a tarefa é concluída.Um retorno de chamada assíncrono é diferente, pois quando a função chamada à qual fornecemos um retorno de chamada retorna, a tarefa pode não ser concluída. Esse tipo de retorno de chamada é frequentemente usado com E / S assíncrona na qual uma operação de E / S é iniciada e, quando concluída, o retorno de chamada é invocado.
No programa a seguir, criamos um soquete para escutar solicitações de conexão TCP e, quando uma solicitação é recebida, a função que escuta chama a função de retorno de chamada fornecida. Esse aplicativo simples pode ser exercitado executando-o em uma janela enquanto você usa o
telnet
utilitário ou um navegador da Web para tentar se conectar em outra janela.Tirei a maior parte do código WinSock do exemplo que a Microsoft fornece com a
accept()
função em https://msdn.microsoft.com/en-us/library/windows/desktop/ms737526(v=vs.85).aspxEsse aplicativo inicia um
listen()
host local, 127.0.0.1, usando a porta 8282, para que você possa usar umtelnet 127.0.0.1 8282
ou outrohttp://127.0.0.1:8282/
.Este aplicativo de exemplo foi criado como um aplicativo de console com o Visual Studio 2017 Community Edition e está usando a versão dos soquetes do Microsoft WinSock. Para um aplicativo Linux, as funções WinSock precisariam ser substituídas pelas alternativas Linux e a biblioteca de threads do Windows usaria
pthreads
.fonte
Os retornos de chamada em C são geralmente implementados usando ponteiros de função e um ponteiro de dados associado. Você passa sua função
on_event()
e ponteiros de dados para uma função de estruturawatch_events()
(por exemplo). Quando um evento acontece, sua função é chamada com seus dados e alguns dados específicos do evento.Os retornos de chamada também são usados na programação da GUI. O tutorial do GTK + tem uma boa seção sobre a teoria dos sinais e retornos de chamada .
fonte
Este artigo da Wikipedia tem um exemplo em C.
Um bom exemplo é que novos módulos escritos para aumentar o servidor da Web Apache se registram no processo principal do apache, passando os ponteiros de função para que essas funções sejam chamadas de volta ao processo de solicitações de páginas da web.
fonte
Geralmente, isso pode ser feito usando um ponteiro de função, que é uma variável especial que aponta para o local da memória de uma função. Você pode usar isso para chamar a função com argumentos específicos. Portanto, provavelmente haverá uma função que define a função de retorno de chamada. Isso aceitará um ponteiro de função e armazenará esse endereço em algum lugar onde ele possa ser usado. Depois disso, quando o evento especificado for acionado, ele chamará essa função.
fonte
É muito mais fácil entender uma idéia através do exemplo. O que foi dito sobre a função de retorno de chamada em C até agora são ótimas respostas, mas provavelmente o maior benefício do uso do recurso é manter o código limpo e organizado.
Exemplo
O código C a seguir implementa a classificação rápida. A linha mais interessante no código abaixo é esta, onde podemos ver a função de retorno de chamada em ação:
O compare_s2b é o nome da função que qsort () está usando para chamar a função. Isso mantém o qsort () tão organizado (portanto, mais fácil de manter). Você apenas chama uma função pelo nome de dentro de outra função (é claro, a declaração do protótipo da função, pelo menos, deve preceder antes que possa ser chamada de outra função).
O Código Completo
fonte