| Uutiset | Koodikirjasto | Wiki | Keskustelut | FAQ | Info |
Extension Ruby-skriptikieleencyndis 10.11.04 14:35 Yksinkertainen 3 FMODin funktiota Rubylle wrappaava extension-esimerkki.
// Extension-kirjaston tekeminen Ruby-skriptikielelle // Tässä esimerkissä wrapataan FMOD-C-kirjaston // funktiot FSOUND_Stream_Close, FSOUND_Stream_Open ja // FSOUND_Stream_Play. Huomaa, että näitä funktioita // voidaan käyttää ainoastaan stream-äänien kanssa, // kuten wav, mp3 ja ogg. // Koodin pitäisi toimia kaikilla alustoilla, joilla Ruby ja FMOD toimivat. // Linkit: // Ruby : http://www.ruby-lang.org/ // FMOD : http://www.fmod.org/ // FMOD-referenssi : http://www.fmod.org/docs/ // Pickaxe Bookin extension-osa : http://www.rubycentral.com/book/ext_ruby.html #include <ruby.h> #include <fmod.h> #include <fmod_errors.h> VALUE fmod_moduuli; VALUE fmod_luokka; VALUE fmod_virhe; static VALUE rubyfmod_lopeta(VALUE self) { FSOUND_Close(); return Qnil; // Älä palauta mitään. } // FMOD::Musiikki-luokan destruktori. static void rubyfmod_vapauta_musiikki(void *ptr) { FSOUND_Stream_Close(ptr); } // FMOD::Musiikki-luokan konstruktori. static VALUE rubyfmod_uusi(VALUE self,VALUE tiedostonimi) { // Tarkista että parametri on String-luokan olio. // Aiheuttaa exceptionin, mikäli ei ole. Check_Type(tiedostonimi,T_STRING); FSOUND_STREAM *stream; // Makro STR2CSTR() muuttaa String-olion C-merkkitaulukoksi. stream = FSOUND_Stream_Open(STR2CSTR(tiedostonimi),0,0,0); if (stream == NULL) { // lataus epäonnistui // Nosta virhe rb_raise(fmod_virhe,FMOD_ErrorString(FSOUND_GetError())); return Qfalse; } else { // rb_iv_set asettaa tässä self-luokan (FMOD::Musiikki) // instanssimuuttujan @stream arvoksi wrapatun FSOUND_STREAMin. // Data_Wrap_Structia pitää käyttää, koska rubyn muuttujiin // ei voi asettaa C-tietotyyppejä. // Data_Wrap_Struct ottaa seuraavat parametrit: // - class (tässä arvo self) on luokka, joka palautetaan, // kun ruby-koodi kysyy @streamin tyyppiä. // - mark (tässä arvo 0) on garbage collectorin mark-käsittelijän // C-funktion nimi. Tässä 0 koska sitä ei käytetä. // - free (tässä arvo rubyfmod_vapauta_musiikki) on garbage collectorin // free-käsittelijän C-funktion nimi, jota kutsutaan // kun objekti poistetaan. // - ptr (tässä arvo stream) on se C-muuttuja, joka halutaan wrapata. rb_iv_set(self,"@stream",Data_Wrap_Struct( fmod_luokka,0,rubyfmod_vapauta_musiikki,stream) ); return Qtrue; } } static VALUE rubyfmod_soita(VALUE self) { FSOUND_STREAM *stream; // Otetaan C-muuttuja Data_Wrap_Structatusta instanssimuuttujasta. // Data_Get_Structin parametrit ovat: // - Ruby-arvo josta muuttuja otetaan (rb_iv_get palauttaa rb_iv_setillä // asetetun muuttujan) // - Palautettava C-tietotyyppi, tässä FSOUND_STREAM ja // - Pointteri muuttujaan johon muuttuja asetetaan. Data_Get_Struct(rb_iv_get(self,"@stream"),FSOUND_STREAM,stream); // Soita vapailla kanavilla (FSOUND_Free) if (FSOUND_Stream_Play(FSOUND_FREE,stream) > 0) { // OK return Qtrue; } else { return Qfalse; } } // Ruby-extensioneissa on aina funktio nimeltä // Init_<extension-nimi>, jota kutsutaan extensionia // ladattaessa. // Extensionin tiedostonimen täytyy myös olla <extension-nimi>.{so/dll} void Init_Musiikki() { FSOUND_Init(44100,32,0); fmod_moduuli = rb_define_module("FMOD"); // Tee luokka "Musiikki" fmod_luokka-muuttujaan ja // periytä luokka rubyn luokasta Object. // Luokka tehdään äsken määritellyn FMOD-moduulin // alle, joten ruby-koodissa se on FMOD::Musiikki. fmod_luokka = rb_define_class_under( fmod_moduuli,"Musiikki",rb_cObject ); fmod_virhe = rb_define_class_under(fmod_moduuli,"Virhe",rb_eStandardError); // Funktiomääritykset, parametrit ovat: // Luokka johon funktio lisätään, // Funktion nimi (initialize on rubysta käytettynä nimellä new), // C-funktio jota kutsutaan ja // montako parametria metodi ottaa. rb_define_method(fmod_luokka,"initialize",rubyfmod_uusi,1); rb_define_method(fmod_luokka,"Soita",rubyfmod_soita,0); // Wrappaa lopetusfunktio rubyn puolelle. rb_define_singleton_method(fmod_moduuli,"lopeta",rubyfmod_lopeta,0); rb_eval_string("Kernel::at_exit {FMOD.lopeta}"); } empty 19:44 11.11.04 En testannut, tosin näyttäis ihan pätevältä esimerkiltä miten tehdään Rubyyn extensioneita. |
![]() Haku
|