- GKO, luennot 5.-7.8.2004
- Säikeet
- Materiaalia:
- Delphi Help: Programming with Delphi, Writing Multi-threaded applications
- Windows SDK: Win32 Programmers Reference, Processes and Threads
- Peruskäsitteitä:
- Windows-sovellus koostuu yhdestä tai useammasta prosessista, joilla kullakin on oma muisti- ja data-alueensa
- Prosessi koostuu yhdestä tai useammasta (mahdollisesti yhtäaikaisesta) säikeestä, jotka jakavat prosessin datan (=voivat kommunikoida globaalien muuttujien avulla)
- Säie on WIN32:n perusyksikkö, jolle järjestelmä jakaa prosessoriaikaa
- Delphissä säikeitä on helppoa käsitellä TThread-luokan avulla
- Thread sisältää Execute-metodin, jonka suorittamisen ajan säie on aktiivinen
- Execute-metodissa on yleensä silmukka, jossa lopetusehtona ainakin Terminated-attribuutin tutkiminen
- Säikeen ollessa aktiivinen ajon voi pysäyttää/jatkaa Suspend/Resume -metodeilla
- Säikeen voi luoda käynninnistettynä tai pysäytettynä
- Delphin TThread-luokka muistuttaa Javan vastaavaa
- Säikeet ja Delphi
- VCL-komponentit ajetaan omassa pääsäikeessään (=eivät ole säieturvallisia!)
- Yleisesti ottaen säikeet ovat Timerita parempi tapa tehdä samanaikaisia toimintoja sovelluksen sisällä
- Jos toisen säikeen on käsiteltävä VCL-komponenttia, se on tehtävä epäsuorasti Synchronize-metodin avulla
- Synchronize odottaa, että pääsäie on päässyt viestisilmukkaan ja suorittaa annetun koodin pääsäikeessä
- Lisäksi Windows tarjoaa runsaasti säikeisiin liittyviä palveluita (Kriittiset alueet, mutexit, semaforit...)
- Säikeiden syvällisempi käsittely menee kurssin yli, mutta säikeiden hallinta on tärkeää erityisesti verkko-ohjelmissa (esim. palvelimet)
- Erityisesti resurssien (tietokantayhteydet, tiedostokahvat, globaalit muuttujat) käsittely monisäikeisessä sovelluksessa pitäisi toteuttaa synkronoidusti
- esim. resurssia käsitellään yksi säie kerrallaan tai säikeiden järjestys on muuten kontrolloitu
- Lisää säikeistä esim. kursseilla Käyttöjärjestelmien perusteet, Hajautetut järjestelmät, Rinnakkaislaskenta
- Esimerkki: automaattilaskuri
- TPC / IP
- Materiaalia:
- Delphi Help: Writing Internet Appications
- Internet Direct Knowledge Base
- [ http://delphi.about.com/od/indy/ ]
- Yleiskatsaus: Introduction to Indy (Chad Z. Hower)
- Jensen & Anderson: Building Kylix Applications -kirja (luvut 20 ja 21 saatavilla verkossa)
- Lisätietoa (ei tule tenttiin...) esim: Sovellusprotokollat-kurssi
- [ http://www.mit.jyu.fi/wikstrom/opetus/tli343/index.html ]
- TCP-määritys
- [ http://www.faqs.org/rfcs/rfc793.html ]
- Kuljetuskerroksen protokolla, takaa luotettavan 2-suuntaisen (yhteydellisen) tiedonsiirron, vrt. UDP
- Huom. esim HTTP toimii tcp/ip:n päällä. Jokaista pyydettävää websivua kohti avataan uusi yhteys, joka suljetaan web-sivun latauduttua
- IP-määritys
- [ http://www.faqs.org/rfcs/rfc791.html ]
- Verkkokerroksen protokolla
- Jokaisella IP-verkkoon kytketyllä laitteella on 32-bittinen IP-osoite (jaettuna yleensä neljään tavuun...)
- Paikalliseen koneeseen voidaan viitata nimellä localhost tai IP-osoitteella 127.0.01
- Porttinumerot
- [ http://www.iana.org/assignments/port-numbers ]
- Kokonaisluku, jolla tunnistetaan käytettävä palvelu
- Palvelin kuuntelee omalle sovellukselleen ominaista porttia
- Tyypillisiä porttinumeroita: HTTP: 80, 8080, FTP: 21, SSH: 22 (portit 1024:ään asti ovat varattuja)
- Huom. porttinumerot eivät takaa, että kysely on tarkoituksenmukainen tai noudattaa oikeaa protokollaa
- (vrt. madot, ddos-hyökkäykset ym)
- Yhteystyyppejä
- Socket-yhteydet
- Standardi rajapinta verkkoprotokollien käyttöön (sekä windowsissa että linuxissa)
- toimivat yleensä TCP/IP-yhteyden päällä, myös muut verkot (esim. Novell) mahdollisia
- Nimetyt putket
- "tiedostomaista" kahden sovelluksen kommunikointia verkon yli
- RPC (Remote Procedure Call)
- Perussovelluksia
- PING - testiyhteys
- TRACERT (traceroute) - selvittää reitityksen osoitteesta toiseen
- Monia TCP/IP -pohjaisia tekstiprotokollia voi testata Telnet -pääteyhteydellä
- Asiakas-palvelin -malli:
- Asiakas on prosessi, joka käynnistää yhteyden palvelimeen (esim. webselain, tietokantasovellus)
- Palvelin on prosessi, joka vastaa pyyntöihin. Samanaikaiset pyynnöt eri käyttäjiltä käsitellään omissa säikeissään (esim. webpalvelin, tietokantapalvelin)
- Delphin verkkokomponentit
- INDY - Internet Direct
- Open Source -verkkokomponenttikokoelma delphille (socket-yhteyksiä, n. 70 asiakas- ja palvelinkomponenttia eri protokollille windowsissa ja linuxissa)
- INDY-komponenttien palvelukutsut ovat blokkaavia (blocking): funktiosta palataan vasta, kun operaatio on suoritettu
- vrt. automaattisesti palaava kutsu: tällöin funktiosta palataan heti ja ohjelmassa täytyy tarkistaa manuaalisesti myöhemmin, mikä oli kutsun tulos
- blokkaavat kutsut soveltuvat käytettäviksi omissa säikeissään
- jos blokkaava kutsu tehdään pääsäikessä, käyttöliittymä saattaa 'pysähtyä', kunnes kutsusta palataan (vrt. yleinen windowsin tapahtumakäsittelijöiden keskeytysongelma)
- INDY-komponentilla TIdAntiFreeze voi korjata pysähtymisongelman, vaikka sovelluksessa ei käytetä erillisiä säikeitä
- vrt. VL:n checker -ohjelmaa
- Minimaalinen TCP-ip -esimerkki TCPClient-kompoentilla
- WebBroker
- Web-palvelinta (esim Apache, IIS) laajentavien palvelinsovellusten tekoon
- WebSnap
- WebBrokeria uudempi ja laajennettu järjestelmä palvelinsovelluksiin
- Pitäisi mahdollistaa visuaalisen dynaamisten web-sivujen kehityksen (ei kokeiltu vielä..) :-)
- Esimerkki: TCP/IP-lomake
- huom. vaatii kaveoptvcl-paketin
- tcp/ip lomake toimii yleiskäyttöisenä tcp-asiakkaana ja palvelimena
- käyttää sisäisesti INDY-komponenttien TCP server ja TCP client -komponentteja
- pääteohjauksissa kokeitavana chat, telnet-yhteys, www-"selain" ja www-"palvelin"
- TCP/IP-lomaketta voi (ja kannattaa!) käyttää apuna, jos harkkatyössä tarvitsee verkkoyhteyksiä
- Omaa "protokollaa" varten voi ottaa mallia esim. VespaCADista
- Vanha tentti ja VespaCAD
- huom. käännä vespacadin paketit (kcomp, vespa) ennen varsinaista ohjelmaa ja varmista, että search path -hakemistossa on kcomp ja tcpip
- Figure on yliluokka piirto-objekteille, tukee mm. skaalausta ja merkkijonoesitystä
- Alusta sisältää figuret, tukee niiden liikutusta raahaamalla, osaa ladata ja tallentaa itsensä tiedostoon
- Orsi säilyttää Figure-tyyppiset oliot, joita voi raahata Alustaan. Figure kopioidaan raahauksessa
- Piirto-ohjelmaa voi ohjata verkon yli TCP/IP-lomakkeen avulla niin, että useampi käyttäjä voi piirtää samanaikaisesti
- Sovellusten välinen kommunikointi
- Materiaalia:
- Kommunikointitapoja
- Tiedostot...
- Perustilanne: yksi sovellus tallentaa tiedostoa sovittuun paikkaan, josta toinen sovellus lukee sitä säännöllisin väliajoin
- Tekstitiedosto (esim. |-erotellut tietueet) on vanha, mutta toimiva siirtoformaatti yksinkertaissen tietoon
- Nykyään myös XML (käytännössä rakenteinen tekstitiedosto) tärkeä siirtoformaatin metakieli
- Siis: XML-formaatti ei ratkaise tiedonsiirto-ongelmaa sinänsä, mutta tarjoaa standardin tavan rakenteistaa tekstiä
- XML:n käsittely on edelleen tehtävä itse (tosin valmiin XML-jäsentimet ja XML data binding -työkalut vähentävät rutiinityötä)
- Ikkunoiden väliset viestit
- Viestinvälitys helppoa, laajojen tietorakenteiden suora välitys pelkillä viesteillä ei ole käytännöllistä
- Soveltuu mm. ilmoitusten välittämiseen sovelluksen tilasta
- Esimerkki: MultiwinMsg
- File Mapping: yhteinen virtuaalinen muistialue tiedostossa
- Lisätietoa Windows SDK:ssa
- Jaettua muistia sovellusten välillä
- Drag & Drop
- Leikepöytä
- Voi sisällyttää saman tiedon monessa eri formaatissa (esim. RTF, teksti)
- Liittämisen aikana kohdesovellukseen kopioidaan yksityiskohtaisin sovelluksen ymmärtämä esitys
- Käytettävyysohje: sovellus ei saa muuttaa leikepöydän sisältöä käyttäjän tietämättä
- DDE
- OLE / ActiveX
- Materiaalia: Microsoft...
- [ http://www.microsoft.com/com/tech/ActiveX.asp ]
- Perusteellinen tutoriaali: dr. gui's gentle introduction to com
- [ http://www.microsoft.com/com/news/drgui.asp ]
- David Chappel & David S. Linthicum: ActiveX demystified
- [ http://www.byte.com/art/9709/sec5/sec5.htm ]
- OLE ja ActiveX ovat COM-pohjaisia teknologioita
- COM == Component Object Model, MicroSoftin kaikenkattava komponenttimalli
- COM-komponentti on kokoelma rajapintoja, joiden avulla komponentin kanssa kommunikoidaan
- Kaikkien COM-komponenttien on toteutettava ainakin IUnknown-rajapinta
- Varo markkinointinimien sekamelskaa:
- COM on yleinen Microsoftin komponenttimalli (ks. yllä)
- DCOM on hajautettu versio COM-mallista
- COM+ transaktioita tukeva hajautettu COM
- OLE tarkoitti alunperin vain yhdistelmädokumentteja (jotka Win95:n myötä määriteltiin COM-pohjaisiksi), mutta sittemmin nimeä on vlljelty eri COM-pohjaisissa tekniikoissa (esim OLEdb, M$:n uudempi tietokantarajapinta)
- ActiveX-kontrollit tunnettiin aiemmin OLE-controlleina, mutta Internet Explorerin myötä M$ tarvitsi uuden nimen WWW:ssä pyöriville sovelluslaajennuksille. Sittemmin myös ActiveX-nimeä on viljelty eri COM-pohjaissa tekniikoissa (esim. ADO == ActiveX Data Objects, oliorajapinta OLEdb-tietolähteisiin)
- OLE = Object Linking and Embedding
- Tarkoittaa käytännössä yhdistelmädokumentteja (Compound Documents), jossa dokumentti kootaan eri ohjelmilla tehdyistä paloista
- Periaatteessa useimpien win-ohjelmien pitäisi tukea, käytännössä tarkein OLE-ohjelmisto on Microsoft Office
- Klassinen esimerkki: Word-dokumentti, joka sisältää taulukon
- Dokumenttipalat voivat olla linkitettyjä (alidokumentti toisessa tiedostossa) tai upotettuja (päätiedosto sisältää alitiedoston)
- Kun alidokumenttia halutaan editoida, editorisovellus tulee pääsovelluksen ali-ikkunaksi
- Pääsovellus ei ota kantaa alisovelluksen tyyppiin
- Seuraus: kaikki OLEa tukevat sovellukset voivat periaatteessa kommunikoida keskenään, vaikka eivät tietäisi mitään toisistaan
- Käytännössä OLE-yhteiskäyttö toimii parhaiten Office-dokumenttien yhteiskäytössä
- Delphi tarjoaa OleContainer-komponentin, jolla OLE-objekteja voi liittää sovellukseen
- ActiveX = COM-pohjaisia visuaalisia komponentteja
- Laajennettu versio OLE-tekniikasta
- Mahdollistavat mm. komponentin muokkaamisen sovelluksen ulkopuolelta määritellyillä rajapintakutsuilla esim. Visual Basicista (automaatio)
- Internet Explorerin myötä myös Internetissä! (tervetuloa uudet virukset ja olematon tietoturvamalli...)
- Esim. Adobe PDF plugin on ActiveX-kontrolli. Huomaa samankaltaisuus OLE-kontrolleihin (Webselaimen sisälle aukeaa "kevennetty" versio adobe readerista)
- Delphi pystyy käyttämään ActiveX-komponentteja osana omia lomakkeita.
- Myös Delphi-komponentit voidaan helposti "julkaista" ActiveX-kontrolleina (koska TComponent on COM-yhteensopiva). Tällöin niitä voi käyttää esim. Visual Basicista.
- Esimerkki: minimaalinen OLE-sovellus OLEContainerilla ja menulla
- Esimerkki: Word-dokumentin ohjaus automaatiolla
- Pääteohjauksissa PDF-dokumentin avaus ActiveX-komponentilla
- Esimerkki: oma makrokieli ja aikataulut
- Makrokielellä voi automatisoida ohjelman toimintaa
- "kevennetty versio" OLE-automaatiosta :-)
- Makrokielen komponentit käyttöohjeineen ovat FormCommands -tiedostossa
- Komennot ovat TParamCommands -luokassa TStrings -säiliössä (hajautustaulu, jossa jokaisen komennon nimeä vastaa metodiosoitin kohdeohjelmaan)
- Makrot ovat erillisiä "ohjelmatiedostoja", makron voi käynnistää ajamalla varsinaisen ohjelman komentoriviltä parametreilla RUN tentti.prg
- Kohdeohjelman pääohjelman alussa tarkistetaan komentoriviparametrit ennen ohjelman varsinaista suoritusta (FormTimeTables.CheckProgram) ja tarvittaessa ajetaan makro-ohjelma. Muussa tapauksessa sovellus käynnistetään normaalisti.
- Kertaus ja tilannekatsaus
- Kertausta: esim. komponentin luominen ja rekisteröinti, tietokantayhteydet, komponentit ja tapahtumat...
- Viikon teema: sovelluksen hajauttaminen ja sovellusten välinen kommunikointi
- Mitä jäljellä:
- Monikieliset ohjelmat
- Avustukset
- Asennusohjelmat
- Java
- .Net
- XML-käyttöliittymät
- => Tutustmista eri tekniikoihin ja apuohjelmiin, tärkein ohjelmointisisältö on käyty jo
- => Sovelletaan aiemmin opittuja asioita
- Harjoitustyön tarkastelua seuraavalla viikolla?
- Rajapinnat (liittymät, interfaces)
- Materiaalia: Delphi Help: Delphi Language Reference, Object Interfaces
- Määrittelee metodeja, jotka luokan pitää toteuttaa
- C++-terminologiassa abstrakti luokka, jossa kaikki metodit pure virtual-tyyppisiä
- Javassa lähes vastaava rajapintamekanismi
- Sekä Delphissä että Javassa yleinen Object-yliluokka
- Rajapinnan määrittely muistuttaa luokkamäärittelyä, mutta metodeille ei tehdä toteutusta
- Delphi-luokkia ei voi moniperiä, mutta ne voivat toteuttaa useita rajapintoja
- Lisätietoa: Heikki Kainulainen: Moniperintä vastaan rajapinnat (LUK)
- Lähes moniperintää vastaava toiminta saadaan koostamalla ja rajapinnoilla (ks. luk-kuva)
- Rajapinnoissa oletuksena IUnknown COM-rajapinnan mukaiset metodit
- QueryInterface - metodi, jolla voi kysyä, toteuttaako olio määrätyn rajapinnan
- Metodin käyttö edellyttää GUID (Globally Unique Identifier) -numeron määräämistä, joka on rajapinnan globaali tunniste
- GUID-määrityksen voi luoda Delphissä CTRL+SHIFT+G - yhdistelmällä
- _AddRef - lisää viitelaskuria
- _Release - vähentää viitelaskuria ja poistaa olion, kun viitelaskuri nollassa
- Viitelaskuria käsitteleviä metodeja kutsutaan automaattisesti
- COM-objekteilla toteutukset ovat pakollisia
- Jos AddRef ja Release eivät toimi, käyttäjän täytyy itse huolehtia muistinhallinnasta
- TInterfacedObject, TInterfacedPersistent ja TComponent sisältävät toimivat toteutukset
- Delphissä rajapinnat ja luokat eivät ole samanarvoisia (erityisesti IS -operaattoria ei voi käyttää rajapintojen kanssa
- Rajapinnan toteuttamisen voi testata IUnknownin QueryInterface-metodilla, Sysutils-kirjaston Supports-funktiolla tai TObject-luokan GetInterface-metodilla
- Interface-esimerkki
- Rajapintojen käyttömahdollisuuksia
- Mahdollistavat selkeän ja toteutuksesta riippumattoman oliosuunnittelun
- "Moniperintä" delegoinnin avulla
- Implements-määre (ks. Delphi help)
- Delegoitavan luokan täytyy olla TAggregatedObject, muuten muistinhallinta ei toimi oikein
- "Adapterien" teko: määritellään rajapinta, jolla voidaan samaistaa eri luokissa olevat loogisesti samanlaiset metodit
- Esim. interface-esimerkin IAsString
- Delphissä ei voi tehdä suoraan toisiinsa viittavia käännösyksiköitä. Tätä voidaan kiertää rajapintoja käyttämällä
- COM- ja CORBA -yhteensopivia komponentteja tehtäessä (tästä lisää myöhemmin)
- DLL
- Materiaalia
- Dynaamisesti linkitetty ohjelmayksikkö
- Dynaamisuudesta seuraa, että kutsuvan ohjelman ei tarvitse tietää kutsuttavan aliohjelman toteutusta
- Kutsurajapinta (parametrityypit ja paluuarvojen tyypit) pitää tietysti tietää!
- Mahdollistaa saman koodin kutsumisen eri kielillä ja kehitysvälineillä
- Huom! Käyttöjärjestelmäriippuvaista
- DLL:ssä oleviin funktioihin on määriteltävä kutsutapa, calling convention - oletuskutsutapa vaihtelee eri kielissä
- kutsutapa vaikuttaa mm. parametrivälityksen järjestykseen käännetyssä konekoodissa
- esim. stdcall, fastcall, pascal
- stdcall-kutsutapa on yhteensopiva c(++)-koodin kanssa
- DLL:ssä olevien tiedon siirrettävyys vaihtelee kehitysvälineittäin
- dll ei itsessään sisällä tyyppitietoja (bpl-tiedostot sisältävät)
- seuraus: windowsin standardityyppejä kayttävät funktiot toimivat aina, mutta...
- esim. visual c++ tukee myög globaalien muuttujien ja luokkien sijoittamista dll:iin, mutta näiden toimivuus muilla kehitysvälineillä on epävarmaa
- delphillä tehtyjen komponenttien ja lomakkeiden hajauttamiseen on parasta käyttää Borlandin pakettitiedostoja
- Ohjelman toteutuksen osia voi vaihtaa "lennossa" ilman, että ohjelmaa tarvitsee kääntää uudelleen
- DLL:t voivat sisältää datan ja koodin lisäksi myös resursseja (bittikarttoja, merkkijonotauluja...)
- Linkitystavat (ks. kuva)
- Staattinen linkitys
- Kaikki käännösyksiköt (c:ssä obj tai lib, pascalissa dcu) linkitetään käännöksen jälkeen yhdeksi tiedostoksi
- jos jotain käännösyksikköä muutetaan, ohjelma täytyy linkittää uudelleen
- Dynaaminen ohjelman käynnistyessä
- C:ssä DLL-tiedostoon viitataan LIB-kirjastolla, joka sisältää tiedon DLL:ssä olevista funktioista (delphillä riittää funktiomääritys external-lisämääreellä)
- LIB-tiedosto linkitetään staattisesti, DLL ladataan ohjelman alussa ja vapautetaan lopussa
- Dynaaminen ajonaikainen
- "Totaalisen dynaaminen" linkitys: DLL:stä ei tarvitse tietää linkitysaikana mitään
- vrt. dynaaminen muistinvaraus: DLL ladataan ja vapautetaan kesken ohjelman suorituksen tarvittaessa
- DLL.n funktiot täytyy "onkia" yksi kerrallaan GetProcAddress-funktiolla ja sijoittaa funktio-osoittimilla paikoilleen
- DLL jaettuna ohjelmatiedostona
- DLL:n koodi ladataan muistiin vain kerran, vaikka useampi ohjelma käyttäisi sitä => muistin säästöä
- Jokainen prosessi saa oman viittauksen globaaliin kekoon, jossa DLL sijaitsee fyysisesti (memory mapping)
- WIN32:ssa dll:n globaalit muuttujat varataan käyttäville sovelluksille erikseen
- jokainen dll sisältää oman muistiavaruutensa
- seuraus: eri sovellukset eivät voi vaihtaa tietoja vain dll:aa käyttämällä
- Huom. VL.n win-monisteessa mainittua globaalien muuttujien ongelmaa ei ole 32-bittisessä windowsissa.
- globaalien muuttujien kanssa edelleen potentiaalisia ongelmia, jos kutsuva sovellus on monisäikeinen
- kun dll-koodi ladataan ohjelmaan, siitä ajetaan alustuskoodi (dll:n 'pääohjelma')
- dll:lle voidaan määritellä myös erillinen 'entry point'-funktio
- entry point-funktiota kutsutaan, kun ohjelma lataa tai poistaa dll:n muistista
- windowsissa kutsutaan myös silloin, kun sovelluksessa käynnistetään tai lopetetaan säie
- Funktioiden nimistä
- C++:lla kirjoitetun DLL.n funktioiden nimet tulevat sekoitetussa (mangled) muodossa
- DLL:ssä olevien funktioiden nimet saa selvitettyä IMPDEF-komentoriviohjelmalla
- Sekoitetun muodon voi välttää viemällä funktiot C-muodossa ( extern "C" { ... })
- ei koske Visual C++:aa :-(
- Delphillä tehdyissä DLL-tiedostoissa ei ongelmia
- Huom! IMPDEF-ohjelmaa voi käyttää myös esim. Windowsin DLL-kirjastoihin selvittämään, mitä API-kutsuja on käytettävissä...
- Esimerkki: pvm