Takaisinkutsut: Lua-funktioiden välittäminen C:lle
Luokaa ffi.cast-funktiolla C-takaisinkutsuja, jotka kutsuvat Lua-koodia.
Takaisinkutsut: Lua-funktioiden välittäminen C:lle on ilmainen Lua Academy-oppitunti CoddyKitissä. Tämä on oppitunti 4/4. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu Lua Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Lua Academy-kurssilla on yhteensä 4 oppituntia.
Mitä C-takaisinkutsut ovat?
Jotkin C-rajapinnat edellyttävät, että niille välitetään funktio-osoitin, jota C-koodi kutsuu myöhemmin. FFI:n ffi.cast-funktiolla Lua-funktioista voidaan luoda C-yhteensopivia funktio-osoittimia.
Takaisinkutsutyypin määrittely
Määritelkää ensin funktio-osoitintyyppi cdefissä.
local ffi = require("ffi")
ffi.cdef[[
typedef void (*callback_t)(int event, void *data);
void register_handler(callback_t cb);
]]Takaisinkutsun luominen
Käärikää Lua-funktio C:n takaisinkutsuksi komennolla ffi.cast("callback_t", luaFunc). Tuloksena on C-funktio-osoitin, jonka voi välittää C-koodille.
local function myHandler(event, data)
print("Event:", event)
end
local cb = ffi.cast("callback_t", myHandler)
lib.register_handler(cb)Takaisinkutsun elinkaari
Säilyttäkää Lua-viite takaisinkutsuolioon (cb). Jos GC käsittelee sen, C-funktio-osoittimen kutsuminen kaataa ohjelman. Tallentakaa se pitkäikäiseen muuttujaan tai taulukkoon.
local callbacks = {} -- prevent GC
callbacks[#callbacks+1] = ffi.cast("callback_t", myHandler)
lib.register_handler(callbacks[#callbacks])Lajittelu C-vertailufunktiolla
Välittäkää Lua-vertailufunktio C:n qsort-funktiolle FFI-takaisinkutsun kautta.
ffi.cdef[[
typedef int (*cmp_t)(const void *a, const void *b);
void qsort(void *base, size_t nmemb, size_t size, cmp_t cmp);
]]
local arr = ffi.new("int[5]", {3,1,4,1,5})
local cmp = ffi.cast("cmp_t", function(a, b)
return ffi.cast("int*", a)[0] - ffi.cast("int*", b)[0]
end)
ffi.C.qsort(arr, 5, ffi.sizeof("int"), cmp)
for i = 0, 4 do io.write(arr[i] .. " ") endTakaisinkutsut ja korutiinit
C:stä kutsutut Lua-takaisinkutsut eivät voi keskeyttää suoritusta (coroutine.yield). C-puoli ei tue Luan korutiinin vaihtamista. Suunnitelkaa takaisinkutsut niin, etteivät ne keskeytä suoritusta.
Upvalue-arvot takaisinkutsuissa
Lua-takaisinkutsut voivat sulkea upvalue-arvoja normaalisti. Näin takaisinkutsut voivat käyttää kontekstia (esimerkiksi oliota tai tilataulukkoa) ilman globaaleja muuttujia.
local function makeHandler(ctx)
return ffi.cast("callback_t", function(event, _)
ctx.lastEvent = event -- upvalue access
end)
endSignaalinkäsittelijät
Rekisteröikää Lua-funktioita Unix-signaalinkäsittelijöiksi FFI:n kautta. Olkaa varovaisia: signaalinkäsittelijöillä on tiukat rajoitukset sille, mitä C-funktioita ne voivat kutsua.
Takaisinkutsujen muistinhallinta
Vapauttakaa takaisinkutsut komennolla cb:free(), kun olette poistaneet niiden rekisteröinnin C-puolelta. Takaisinkutsuolioiden vuotaminen tuhlaa muistia.
Vaihtoehto: C-wrapper-funktiot
Monimutkaisissa integraatioissa ohut C-sovitin voi olla FFI-takaisinkutsuja selkeämpi. Sovitin kutsuu Luaa C API:n kautta ja tarjoaa täyden hallinnan korutiineihin ja virheenkäsittelyyn.
Suorituskyky
FFI-takaisinkutsut ovat nopeita, mutta eivät yhtä nopeita kuin suorat FFI-kutsut, koska C:n ja Luan välinen silta aiheuttaa valmistelukustannuksia. Harkitkaa erittäin usein kutsuttavissa takaisinkutsuissa (esimerkiksi audiossa) puhtaasti C:llä toteutettuja ratkaisuja.
Callback-kysymys
Miksi FFI-takaisinkutsuobjektista on säilytettävä Lua-viite?
Kertaus: FFI-takaisinkutsut
Luokaa C-yhteensopivia takaisinkutsuja käyttämällä ffi.cast("fn_ptr_type", luaFunc)-kutsua. Säilyttäkää aina viite, jotta roskienkeruu ei poista objektia. Takaisinkutsut eivät voi yieldata. Välittäkää konteksti takaisinkutsuihin upvalue-arvojen avulla.
Opi Lua tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 40
- Oppitunnit
- 159
Usein kysytyt kysymykset
Onko oppitunti ”Takaisinkutsut: Lua-funktioiden välittäminen C:lle” ilmainen?
Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa Lua Academy-oppimispolun 3 oppituntia, myös oppitunnin “Takaisinkutsut: Lua-funktioiden välittäminen C:lle”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Lua Academy-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”Takaisinkutsut: Lua-funktioiden välittäminen C:lle”?
Luokaa ffi.cast-funktiolla C-takaisinkutsuja, jotka kutsuvat Lua-koodia. Harjoittelet Lua Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni Lua Academy-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin Lua Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 4/4.
Kuinka kauan ”Takaisinkutsut: Lua-funktioiden välittäminen C:lle”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä Lua Academy-oppitunnilla?
Kyllä. Jokainen Lua Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- FFI:n perusteet: ffi.cdef ja ffi.load
- C-funktioiden kutsuminen FFI:n kautta
- Osoittimet, rakenteet ja taulukot FFI:ssä
- Takaisinkutsut: Lua-funktioiden välittäminen C:lle