What is a "callback" in C and how are they implemented?

文章推薦指數: 80 %
投票人數:10人

A callback in C is a function that is provided to another function to "call back to" at some point ... Resultsfromthe2022DeveloperSurveyarenowavailable Home Public Questions Tags Users Companies Collectives ExploreCollectives Teams StackOverflowforTeams –Startcollaboratingandsharingorganizationalknowledge. CreateafreeTeam WhyTeams? Teams CreatefreeTeam Collectives™onStackOverflow Findcentralized,trustedcontentandcollaboratearoundthetechnologiesyouusemost. Learnmore Teams Q&Aforwork Connectandshareknowledgewithinasinglelocationthatisstructuredandeasytosearch. Learnmore Whatisa"callback"inCandhowaretheyimplemented? AskQuestion Asked 13years,9monthsago Modified 3years,6monthsago Viewed 334ktimes 170 122 FromthereadingthatIhavedone,CoreAudioreliesheavilyoncallbacks(andC++,butthat'sanotherstory). Iunderstandtheconcept(sortof)ofsettingupafunctionthatiscalledbyanotherfunctionrepeatedlytoaccomplishatask.Ijustdon'tunderstandhowtheygetsetupandhowtheyactuallywork.Anyexampleswouldbeappreciated. ccallback Share Follow editedDec23,2016at15:09 SouravGhosh 131k1616goldbadges177177silverbadges247247bronzebadges askedSep27,2008at2:32 noizetoysnoizetoys 2,80355goldbadges2323silverbadges1515bronzebadges Addacomment  |  9Answers 9 Sortedby: Resettodefault Highestscore(default) Trending(recentvotescountmore) Datemodified(newestfirst) Datecreated(oldestfirst) 232 Thereisno"callback"inC-notmorethananyothergenericprogrammingconcept. They'reimplementedusingfunctionpointers.Here'sanexample: voidpopulate_array(int*array,size_tarraySize,int(*getNextValue)(void)) { for(size_ti=0;icb(event,callback->data); Share Follow answeredSep29,2008at1:47 RussellBryantRussellBryant 1,60111goldbadge1010silverbadges88bronzebadges 4 1 JustwhatIneeded.Theuserdatapartisveryhelpfulifyouruserswanttopasscustomdata(e.g.devicehandles)requiredinthcallbackfunction. – uceumern Jul30,2015at12:59 verificationquestion:Isthecallbacktypedefwithanasteriskbecauseitisapointertothefunctionaddress?Iftheasteriskismissing,wouldthatbeincorrect?Ifthatisincorrectthentherearetwomissingstarsinthelibsrtplibraryofciscoongithub:github.com/cisco/libsrtp/blob/…github.com/cisco/libsrtp/blob/… – twildeman Nov7,2017at10:13 @twildemanItseemstrivialtoansweryourownquestionbycompilinginaStandardCmodewithwarningson.Youcanalsowriteaminimisedtestprogram.Codesuchasthoseinlibsrtpgivesnowarnings.Ipresume,then,thatwhensuchatypeappearsasafunctionargument,itisrequiredto'decay'toapointer-to-function,justlikearraysdecaytopointerstotheirfirstelements,sothesamethinghappensintheendeitherway.Itisinteresting,though,thatdiscussionsofsuchtypedefsI'vefounddon'tevenglanceatthisaspect,ratherfocusondeclaringprototypesorpointerswithit – underscore_d Jan12,2019at15:46 Ihavenoideawhatthisdoes,andit'sunabletobecompiledsuccessfully.Cananyoneexplainitindetailedwayorfilltherestofthecodeupinorderforcompilesuccessfully? – AndyLin Jun9,2020at10:14 Addacomment  |  25 Asimplecallbackprogram.Hopeitanswersyourquestion. #include #include #include #include #include #include"../../common_typedef.h" typedefvoid(*call_back)(S32,S32); voidtest_call_back(S32a,S32b) { printf("Incallbackfunction,a:%d\tb:%d\n",a,b); } voidcall_callback_func(call_backback) { S32a=5; S32b=7; back(a,b); } S32main(S32argc,S8*argv[]) { S32ret=SUCCESS; call_backback; back=test_call_back; call_callback_func(back); returnret; } Share Follow editedJun14,2013at12:37 Cleankod 2,13055goldbadges3030silverbadges5050bronzebadges answeredNov27,2012at9:11 GauthamKantharajuGauthamKantharaju 1,66511goldbadge2020silverbadges2424bronzebadges 0 Addacomment  |  9 AcallbackfunctioninCistheequivalentofafunctionparameter/variableassignedtobeusedwithinanotherfunction.WikiExample Inthecodebelow, #include #include /*Thecallingfunctiontakesasinglecallbackasaparameter.*/ voidPrintTwoNumbers(int(*numberSource)(void)){ printf("%dand%d\n",numberSource(),numberSource()); } /*Apossiblecallback*/ intoverNineThousand(void){ return(rand()%1000)+9001; } /*Anotherpossiblecallback.*/ intmeaningOfLife(void){ return42; } /*HerewecallPrintTwoNumbers()withthreedifferentcallbacks.*/ intmain(void){ PrintTwoNumbers(&rand); PrintTwoNumbers(&overNineThousand); PrintTwoNumbers(&meaningOfLife); return0; } Thefunction(*numberSource)insidethefunctioncallPrintTwoNumbersisafunctionto"callback"/executefrominsidePrintTwoNumbersasdictatedbythecodeasitruns. Soifyouhadsomethinglikeapthreadfunctionyoucouldassignanotherfunctiontoruninsidetheloopfromitsinstantiation. Share Follow editedSep7,2015at1:08 answeredSep7,2015at1:03 daemondavedaemondave 17911silverbadge1111bronzebadges Addacomment  |  9 AcallbackinCisafunctionthatisprovidedtoanotherfunctionto"callbackto"atsomepointwhentheotherfunctionisdoingitstask. Therearetwowaysthatacallbackisused:synchronouscallbackandasynchronouscallback.Asynchronouscallbackisprovidedtoanotherfunctionwhichisgoingtodosometaskandthenreturntothecallerwiththetaskcompleted.Anasynchronouscallbackisprovidedtoanotherfunctionwhichisgoingtostartataskandthenreturntothecallerwiththetaskpossiblynotcompleted. Asynchronouscallbackistypicallyusedtoprovideadelegatetoanotherfunctiontowhichtheotherfunctiondelegatessomestepofthetask.Classicexamplesofthisdelegationarethefunctionsbsearch()andqsort()fromtheCStandardLibrary.Bothofthesefunctionstakeacallbackwhichisusedduringthetaskthefunctionisprovidingsothatthetypeofthedatabeingsearched,inthecaseofbsearch(),orsorted,inthecaseofqsort(),doesnotneedtobeknownbythefunctionbeingused. Forinstancehereisasmallsampleprogramwithbsearch()usingdifferentcomparisonfunctions,synchronouscallbacks.Byallowingustodelegatethedatacomparisontoacallbackfunction,thebsearch()functionallowsustodecideatruntimewhatkindofcomparisonwewanttouse.Thisissynchronousbecausewhenthebsearch()functionreturnsthetaskiscomplete. #include #include #include typedefstruct{ intiValue; intkValue; charlabel[6]; }MyData; intcmpMyData_iValue(MyData*item1,MyData*item2) { if(item1->iValueiValue)return-1; if(item1->iValue>item2->iValue)return1; return0; } intcmpMyData_kValue(MyData*item1,MyData*item2) { if(item1->kValuekValue)return-1; if(item1->kValue>item2->kValue)return1; return0; } intcmpMyData_label(MyData*item1,MyData*item2) { returnstrcmp(item1->label,item2->label); } voidbsearch_results(MyData*srch,MyData*found) { if(found){ printf("found-iValue=%d,kValue=%d,label=%s\n",found->iValue,found->kValue,found->label); }else{ printf("itemnotfound,iValue=%d,kValue=%d,label=%s\n",srch->iValue,srch->kValue,srch->label); } } intmain() { MyDatadataList[256]={0}; { inti; for(i=0;i<20;i++){ dataList[i].iValue=i+100; dataList[i].kValue=i+1000; sprintf(dataList[i].label,"%2.2d",i+10); } } //...somecodethenwedoasearch { MyDatasrchItem={105,1018,"13"}; MyData*foundItem=bsearch(&srchItem,dataList,20,sizeof(MyData),cmpMyData_iValue); bsearch_results(&srchItem,foundItem); foundItem=bsearch(&srchItem,dataList,20,sizeof(MyData),cmpMyData_kValue); bsearch_results(&srchItem,foundItem); foundItem=bsearch(&srchItem,dataList,20,sizeof(MyData),cmpMyData_label); bsearch_results(&srchItem,foundItem); } } Anasynchronouscallbackisdifferentinthatwhenthecalledfunctiontowhichweprovideacallbackreturns,thetaskmaynotbecompleted.ThistypeofcallbackisoftenusedwithasynchronousI/OinwhichanI/Ooperationisstartedandthenwhenitiscompleted,thecallbackisinvoked. InthefollowingprogramwecreateasockettolistenforTCPconnectionrequestsandwhenarequestisreceived,thefunctiondoingthelisteningtheninvokesthecallbackfunctionprovided.Thissimpleapplicationcanbeexercisedbyrunningitinonewindowwhileusingthetelnetutilityorawebbrowsertoattempttoconnectinanotherwindow. IliftedmostoftheWinSockcodefromtheexampleMicrosoftprovideswiththeaccept()functionathttps://msdn.microsoft.com/en-us/library/windows/desktop/ms737526(v=vs.85).aspx Thisapplicationstartsalisten()onthelocalhost,127.0.0.1,usingport8282soyoucoulduseeithertelnet127.0.0.18282orhttp://127.0.0.1:8282/. ThissampleapplicationwascreatedasaconsoleapplicationwithVisualStudio2017CommunityEditionanditisusingtheMicrosoftWinSockversionofsockets.ForaLinuxapplicationtheWinSockfunctionswouldneedtobereplacedwiththeLinuxalternativesandtheWindowsthreadslibrarywouldusepthreadsinstead. #include #include #include #include #include //NeedtolinkwithWs2_32.lib #pragmacomment(lib,"Ws2_32.lib") //functionforthethreadwearegoingtostartupwith_beginthreadex(). //thisfunction/threadwillcreatealistenserverwaitingforaTCP //connectionrequesttocomeintothedesignatedport. //_stdcallmodifierrequiredby_beginthreadex(). int_stdcallioThread(void(*pOutput)()) { //---------------------- //InitializeWinsock. WSADATAwsaData; intiResult=WSAStartup(MAKEWORD(2,2),&wsaData); if(iResult!=NO_ERROR){ printf("WSAStartupfailedwitherror:%ld\n",iResult); return1; } //---------------------- //CreateaSOCKETforlisteningfor //incomingconnectionrequests. SOCKETListenSocket; ListenSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if(ListenSocket==INVALID_SOCKET){ wprintf(L"socketfailedwitherror:%ld\n",WSAGetLastError()); WSACleanup(); return1; } //---------------------- //Thesockaddr_instructurespecifiestheaddressfamily, //IPaddress,andportforthesocketthatisbeingbound. structsockaddr_inservice; service.sin_family=AF_INET; service.sin_addr.s_addr=inet_addr("127.0.0.1"); service.sin_port=htons(8282); if(bind(ListenSocket,(SOCKADDR*)&service,sizeof(service))==SOCKET_ERROR){ printf("bindfailedwitherror:%ld\n",WSAGetLastError()); closesocket(ListenSocket); WSACleanup(); return1; } //---------------------- //Listenforincomingconnectionrequests. //onthecreatedsocket if(listen(ListenSocket,1)==SOCKET_ERROR){ printf("listenfailedwitherror:%ld\n",WSAGetLastError()); closesocket(ListenSocket); WSACleanup(); return1; } //---------------------- //CreateaSOCKETforacceptingincomingrequests. SOCKETAcceptSocket; printf("Waitingforclienttoconnect...\n"); //---------------------- //Accepttheconnection. AcceptSocket=accept(ListenSocket,NULL,NULL); if(AcceptSocket==INVALID_SOCKET){ printf("acceptfailedwitherror:%ld\n",WSAGetLastError()); closesocket(ListenSocket); WSACleanup(); return1; } else pOutput();//wehaveaconnectionrequestsodothecallback //Nolongerneedserversocket closesocket(ListenSocket); WSACleanup(); return0; } //ourcallbackwhichisinvokedwheneveraconnectionismade. voidprintOut(void) { printf("connectionreceived.\n"); } #include intmain() { //startupourlistenserverandprovideacallback _beginthreadex(NULL,0,ioThread,printOut,0,NULL); //dootherthingswhilewaitingforaconnection.Inthiscase //justsleepforawhile. Sleep(30000); } Share Follow editedDec5,2018at3:13 adabsurdum 18k55goldbadges3333silverbadges5454bronzebadges answeredMar2,2018at16:03 RichardChambersRichardChambers 15.7k33goldbadges7373silverbadges101101bronzebadges 1 Excellentanswer,showingbothsynchronousandasynchronouscall-backs.Anotherconcreteexampleoftheuseofasynchronouscall-backsinC-*NIXareasynchronoussignalsandtheirsignalhandlers.HereisanexcellentdescriptionofhowsignalhandlersareprocessedinLinux[link](stackoverflow.com/questions/6949025/…). – drlolly May19,2020at10:21 Addacomment  |  4 CallbacksinCareusuallyimplementedusingfunctionpointersandanassociateddatapointer.Youpassyourfunctionon_event()anddatapointerstoaframeworkfunctionwatch_events()(forexample).Whenaneventhappens,yourfunctioniscalledwithyourdataandsomeevent-specificdata. CallbacksarealsousedinGUIprogramming.TheGTK+tutorialhasanicesectiononthetheoryofsignalsandcallbacks. Share Follow answeredSep27,2008at2:36 JohnMillikinJohnMillikin 191k3939goldbadges208208silverbadges222222bronzebadges Addacomment  |  2 ThiswikipediaarticlehasanexampleinC. AgoodexampleisthatnewmoduleswrittentoaugmenttheApacheWebserverregisterwiththemainapacheprocessbypassingthemfunctionpointerssothosefunctionsarecalledbacktoprocesswebpagerequests. Share Follow answeredSep27,2008at2:41 LeonardLeonard 13k88goldbadges4444silverbadges7171bronzebadges 0 Addacomment  |  1 Itisloteasiertounderstandanideathroughexample. WhathavebeentoldaboutcallbackfunctioninCsofararegreatanswers,butprobablythebiggestbenefitofusingthefeatureistokeepthecodecleananduncluttered. Example ThefollowingCcodeimplementsquicksorting. Themostinterestinglineinthecodebelowisthisone,wherewecanseethecallbackfunctioninaction: qsort(arr,N,sizeof(int),compare_s2b); Thecompare_s2bisthenameoffunctionwhichqsort()isusingtocallthefunction.Thiskeepsqsort()souncluttered(henceeasiertomaintain).Youjustcallafunctionbynamefrominsideanotherfunction(ofcourse,thefunctionprototypedeclaration,attheleast,mustprecdebeforeitcanbecalledfromanotherfunction). TheCompleteCode #include #include intarr[]={56,90,45,1234,12,3,7,18}; //functionprototypedeclaration intcompare_s2b(constvoid*a,constvoid*b); intcompare_b2s(constvoid*a,constvoid*b); //arrangesthearraynumberfromthesmallesttothebiggest intcompare_s2b(constvoid*a,constvoid*b) { constint*p=(constint*)a; constint*q=(constint*)b; return*p-*q; } //arrangesthearraynumberfromthebiggesttothesmallest intcompare_b2s(constvoid*a,constvoid*b) { constint*p=(constint*)a; constint*q=(constint*)b; return*q-*p; } intmain() { printf("Beforesorting\n\n"); intN=sizeof(arr)/sizeof(int); for(inti=0;iand#include"filename"? 1075 Whatisthedifferencebetween++iandi++? 2972 Howdoyouset,clear,andtoggleasinglebit? 795 Whatisacallbackfunction? 1658 Whatisthedifferencebetweenconstint*,constint*const,andintconst*? 962 HowcanIpassaparametertoasetTimeout()callback? 982 Whatisthedifferencebetweenadefinitionandadeclaration? 1761 Howtoaccessthecorrect`this`insideacallback 828 HowdoIconvertanexistingcallbackAPItopromises? HotNetworkQuestions Howtoapplyudevruletoanon-partitionedlocaldisk? Doesmycathatemenow TCP-WhydoRSTpacketsnotrequireacknowledgements(andFINpacketsdo)? WhydoIgetaccostedfortakingphotosofawarmemorial? Howdoessoapunderminethechurchin"AConnecticutYankee"? Hiomneslingua:Whylinguaisputinsingular? Howtobendastraightstripintoacompletecircle? Whydoprogunandantiabortion(andviceversa)viewsgotogetherintheUSA? DoesBitcoinfeedependonamount? Whatisthis"padding"onscrews? Whatdoes"verynature"ofaservantmeaninPhilippians2:7? HowdoImakeaprogramquitwith"q"andrestoretheconsolelike"man"does? Ifsomesentencehastruth,coulditbecalledsarcasm Canthepatentandpaperhavedifferentauthors(assumetheyincludethesamecontent)? Primingfortheprimes JustificationforaMagicschoolbeingdangerous Children’sbookwithamousecalledNils HowcanIrecovermylosttimeinmycareer? WhatisaTensor,intuitively? HowcanItellmybossthatmyproductivityislowduetoaconflictwithacoworker,withoutblamingthecoworker? Ican'tfindtheGeoreferencer Whydoesthegovernmentnotintroduceanamendmenttotheconstitutiontoallowabortion? HP2000FTSBportedtoMSP430FR5994 WhatarethemainargumentsusedbyChristianpro-liferstojustifytheirstanceagainstabortion? morehotquestions Questionfeed SubscribetoRSS Questionfeed TosubscribetothisRSSfeed,copyandpastethisURLintoyourRSSreader. lang-c Yourprivacy Byclicking“Acceptallcookies”,youagreeStackExchangecanstorecookiesonyourdeviceanddiscloseinformationinaccordancewithourCookiePolicy. Acceptallcookies Customizesettings  



請為這篇文章評分?