Unittien näkyvyysalueet?

Anonyymi

Mietin tuossa, pitääko uniteissa käyttää aina funktio-rajapintaa vai
voiko olla myös globaaleja muuttujia? Ts. mitkä ovat muuttujien näkyvyysalueet uniteissa? Tuolla esimerkissä ainakin kaikki oli funktioissa:
https://www.tutorialspoint.com/pascal/pascal_units.htm

3

134

    Vastaukset

    Anonyymi (Kirjaudu / Rekisteröidy)
    5000
    • Anonyymi

      Funktion sisällä määritellyt on funktion paikallisia, yksikössä (unit) määritellyt muuttujat tavoittaa kaikki yksikön sisältämät funktiot ja procedure rutiinit.

      Esimerkki:
      var a : string;
      implementation
      var s : string;

      procedure gg;
      var t :string;
      begin
      end.

      function ff;
      var x : string
      begin
      end

      a -muuttuja näkyy myös muille yksiköille, ja s näkyy vain tässä yksikössä, t -muuttuja näkyy vain gg-rutiinin sisällä ja x -muuttuja näkyy vain ff -funktion sisällä.

      • Anonyymi

        Anonyymi (18.10.2021 17:52) on aivan oikeassa -juuri näin.

        Pääsääntö: Globaalit muuttujat ovat huono ohjelmointitapa, ja niiden käyttöä on pääsääntöisesti vältettävä.

        Mutta joissain erityistapauksissa Globaalit muuttujat ovat hyvä ja tarpeellinen idea.

        Kannattaa myös huomata:

        Virallisesti Windows API ja DLL:t eivät ole koskaan tukeneet muuttujien exportointia / importointia !

        Jotkut vapaan lähdekoodin ohjelmat ovat ilmeisesti väärinkäyttäneet funktioiden exportointia siten, että on exportoitu muuttujan osoite ikään kuin se olisi funktion osoite.

        JOS esim. C -kielellä tehdyssä DLL:ssä on näin tehty, oma suositukseni on:

        Oletetaan, että muuttujan nimi on X ja se on C-kielellä int -tyyppiä.

        Jos se on exportoitu nimellä X, toimi näin:

        Unit something;

        interface

        function GetAddressOfX:Pointer;

        implementation

        function X(); cdecl; external 'Libary_Made_In_C.DLL';

        function GetAddressOfX:Pointer;
        begin
        Result := @X;
        end;

        Kutsumalla funktiota GetAddressOfX, se palauttaa Pointer -tyyppisen osoittimen, joka osoittaa tuohon sääntöjen vastaisesti exportoituun muuttujaan X.

        Voit sitten tehdä näin:

        var
        P : PInteger;

        begin
        P := GetAddressOfX;
        end;

        esim. ns. singleton -luokan osalta voisi olla hyvä idea:

        globaali muuttuja:

        var
        MySingleton : TMySingleton;
        SingletonTeardown : Boolean;


        ja sitten:

        initialization

        MySingleton : TMySingleton.Create( {parametrit tähän, jos niitä on} );

        finalization
        SingletonTeardown := True;
        FreeAndNil(MySingleton);
        end.

        1-säikeisessä ohjelmassa tämä riittääkin.

        Monisäikeisessä ohjelmassa pitää vielä miettiä, miten voit toisesta säikeestä turvallisesti käyttää MySingleton -muuttujan viittaamaa TMySingleton -tyyppistä luokkaa - kas kun se olio voi yht'äkkiä kadota, kun toinen säie päätyy tuohon

        FreeAndNil(MySingleton); -kohtaan !

        Monisäikeinen ohjelmointi ei tämän takia aina ole helppoa eikä yksinkertaista.

        Pitäisikö kaikki TMySingleton -luokan metodit koodata näin:

        procedure TMySingleton.Esimerkki;
        begin
        FSingletonLock.Acquire;
        try
        // tee varsinainen asia tässä

        finally
        FSingletonLock.Release;
        end;
        end;

        Tuo muuten toimisi, mutta tuo FreeAndNil -käskyn jälkeen mitään TMySingleton -luokan metodia ei saisi kutsua !


      • Anonyymi
        Anonyymi kirjoitti:

        Anonyymi (18.10.2021 17:52) on aivan oikeassa -juuri näin.

        Pääsääntö: Globaalit muuttujat ovat huono ohjelmointitapa, ja niiden käyttöä on pääsääntöisesti vältettävä.

        Mutta joissain erityistapauksissa Globaalit muuttujat ovat hyvä ja tarpeellinen idea.

        Kannattaa myös huomata:

        Virallisesti Windows API ja DLL:t eivät ole koskaan tukeneet muuttujien exportointia / importointia !

        Jotkut vapaan lähdekoodin ohjelmat ovat ilmeisesti väärinkäyttäneet funktioiden exportointia siten, että on exportoitu muuttujan osoite ikään kuin se olisi funktion osoite.

        JOS esim. C -kielellä tehdyssä DLL:ssä on näin tehty, oma suositukseni on:

        Oletetaan, että muuttujan nimi on X ja se on C-kielellä int -tyyppiä.

        Jos se on exportoitu nimellä X, toimi näin:

        Unit something;

        interface

        function GetAddressOfX:Pointer;

        implementation

        function X(); cdecl; external 'Libary_Made_In_C.DLL';

        function GetAddressOfX:Pointer;
        begin
        Result := @X;
        end;

        Kutsumalla funktiota GetAddressOfX, se palauttaa Pointer -tyyppisen osoittimen, joka osoittaa tuohon sääntöjen vastaisesti exportoituun muuttujaan X.

        Voit sitten tehdä näin:

        var
        P : PInteger;

        begin
        P := GetAddressOfX;
        end;

        esim. ns. singleton -luokan osalta voisi olla hyvä idea:

        globaali muuttuja:

        var
        MySingleton : TMySingleton;
        SingletonTeardown : Boolean;


        ja sitten:

        initialization

        MySingleton : TMySingleton.Create( {parametrit tähän, jos niitä on} );

        finalization
        SingletonTeardown := True;
        FreeAndNil(MySingleton);
        end.

        1-säikeisessä ohjelmassa tämä riittääkin.

        Monisäikeisessä ohjelmassa pitää vielä miettiä, miten voit toisesta säikeestä turvallisesti käyttää MySingleton -muuttujan viittaamaa TMySingleton -tyyppistä luokkaa - kas kun se olio voi yht'äkkiä kadota, kun toinen säie päätyy tuohon

        FreeAndNil(MySingleton); -kohtaan !

        Monisäikeinen ohjelmointi ei tämän takia aina ole helppoa eikä yksinkertaista.

        Pitäisikö kaikki TMySingleton -luokan metodit koodata näin:

        procedure TMySingleton.Esimerkki;
        begin
        FSingletonLock.Acquire;
        try
        // tee varsinainen asia tässä

        finally
        FSingletonLock.Release;
        end;
        end;

        Tuo muuten toimisi, mutta tuo FreeAndNil -käskyn jälkeen mitään TMySingleton -luokan metodia ei saisi kutsua !

        Korjaus edelliseen:

        "
        implementation

        function X(); cdecl; external 'Libary_Made_In_C.DLL';

        function GetAddressOfX:Pointer;
        begin
        Result := @X;
        end;

        Kutsumalla funktiota GetAddressOfX, se palauttaa Pointer -tyyppisen osoittimen, joka osoittaa tuohon sääntöjen vastaisesti exportoituun muuttujaan X.
        "

        TEORIASSA tuon pitäisi toimia.
        Mutta veikkaanpa, ettei oikeasti toimi, ja siihen on syykin, miksei toimi.

        Tuo johtuu siitä, että tuo lause:

        Result := @X;

        palauttaa kylläkin muistiosoitteen (mutta todennäköisesti väärän asian muistiosoitteen) ja palauttaa tuon muistiosoitteen GetAddressOfX:Pointer -funktion tuloksena.

        Ongelma liittyy tapaan, jolla ainakin Delphi (ja mahdollisesti myös FreePascal) importoi funktioita DLL;stä, jos ei käytetä ajonaikaista importointitapaa eli LoadLibrary() ja GetProcAddress().

        Helpoin tapa kiertää ongelma on nimenomaan käyttää ajonaikaista importointitapaa eli LoadLibrary() ja GetProcAddress() -funktioita, tällöin homma toimii oikein.

        JOS noin ei halua tehdä, kyllä olisi mahdollista kirjoittaa funktio, joka tekee silti oikean asian, mutta se funktio ei ole ihan noin yksinkertainen kuin edellisessä viestissä on esitetty.


    Ketjusta on poistettu 0 sääntöjenvastaista viestiä.

    Luetuimmat keskustelut

    1. Kiitos nainen

      Kuitenkin. Olet sitten ajanmerkkinä. Tuskin enää sinua näen ja huomasitko, että olit siinä viimeisen kerran samassa paik
      Tunteet
      18
      5323
    2. MTV: Kirkossa saarnan pitänyt Jyrki 69 koki yllätyksen - Paljastaa: "Se mikä oli hyvin erikoista..."

      Jyrki Linnankivi alias Jyrki 69 on rokkari ja kirkonmies. Teologiaa opiskeleva Linnankivi piti elämänsä ensimmäisen saar
      Maailman menoa
      116
      2770
    3. Tykkään sinusta ikuisesti

      Olet niin mukava ja ihana ihminen rakas. ❤️
      Ikävä
      11
      2330
    4. Hyväksytkö sinä sen että päättäjämme ei rakenna rauhaa Venäjän kanssa?

      Vielä kun sota ehkäpä voitaisiin välttää rauhanponnisteluilla niin millä verukkeella voidaan sanoa että on hyvä asia kun
      Maailman menoa
      592
      2037
    5. Kirjoita yhdellä sanalla

      Joku meihin liittyvä asia, mitä muut ei tiedä. Sen jälkeen laitan sulle wappiviestin
      Ikävä
      123
      1756
    6. Olet hyvin erilainen

      Herkempi, ajattelevaisempi. Toisaalta taas hyvin varma siitä mitä haluat. Et anna yhtään periksi. Osaat myös ilkeillä ja
      Ikävä
      70
      1352
    7. Yksi syy nainen miksi sinusta pidän

      on se, että tykkään luomusta. Olet luonnollinen, ihana ja kaunis. Ja luonne, no, en ole tavannut vielä sellaista, joka s
      Ikävä
      42
      1325
    8. Paljastavat kuvat Selviytyjät Suomi kulisseista - 1 päivä vs 36 päivää viidakossa - Katso tästä!

      Ohhoh! Yli kuukausi viidakossa voi muuttaa ulkonäköä perusarkeen aika rajusti. Kuka mielestäsi muuttui eniten: Mia Mill
      Suomalaiset julkkikset
      3
      1098
    9. Veda uskonto vs. muut uskonnot

      Mitenkähän tuo Veda(Krisha)uskonto loppujen lopuksi eroaa muista niin sanotuista ilmoitus uskonnoista? Siinäkin vedotaan
      Ateismi
      393
      1063
    10. Hyvää Joulua mies!

      Toivottavasti kaikki on hyvin siellä. Anteeksi että olen hieman lisännyt taakkaasi ymmärtämättä kunnolla tilannettasi, o
      Ikävä
      64
      1057
    Aihe