Delphillä assemblerin+merkkijonojen käyttö helppoa !

Delphifani80

Delphillä myös assemblerin käyttö koodissa on helppoa, kuten (myös binääristen) merkkijonojenkin !

Seuraava funktio esimerkiksi palauttaa merkkojonon, jonka arvo on prosessoristasi riippuen esim.

'genuineIntel'
'AuthenticAmd' jne ...

function CpuBrandID:String;
begin
SetLength(Result, 12);
asm
push EBX
push EDI
mov EAX,Result
mov EDI,[eax]
xor EAX,EAX
CPUID
cld
mov [edi], ebx
mov [edi 4], edx
mov [edi 8], ecx
pop EDI
pop EBX
end;
end;

Samalla paljastuu se asia, että vaikka objectpascalissa voikin tehdä tyyppimuunnoksen tähän tapaan:

var
St1 : String;
P : PChar;

begin
St1 := CpuBrandID;
P := PChar(St1);
end;

niin konekielikoodin kannalta tuo string onkin enemmänkin PPChar kuin PChar !

C-koodaajille siis:

enemmänkin char ** kuin char * !

Kuitenkin, jos Delphi -koodi ja C -koodi pitää saada keskustelemaan keskenään, niin yleensä homma kuitenkin hoidetaan näin:

### jokudll.c tai jokudll.cpp:

#ifdef CPP
extern "C" {
#endif

void omafunktio(char * Value) {

}

#ifdef CPP
}
#endif

...

ja sitten delphissä näin:

### jokudllimpu.pas:

unit jokudllimpu;

procedure omafunktio(Value:PChar); cdecl; external 'jokudll.dll';

tämän jälkeen kun kutsut delphissä omafunktio(PChar(St1));

niin se kutsuu jokudll.dll:ssä olevaa C:llä koodattua omafunktio -funktiota välittäen sille St1:String -muuttujan, mutta PChar:ksi muunnettuna.

huomaa: C -koodissa ei ole syytä muuttaa merkkijonoa, varsinkaan sen pituutta !

Ja jos sen arvoakaan muutetaan C-koodissa, olisi Delphissä ennen ko. funktiokutsua suoritettava:

UniqueString(St1);

Tuon UniqueString:n ansiosta C -koodi voi muuttaa muuttujan St1 arvoa, kuitenkin siten, että sen pituus ei muutu.

Jos pituutta on tarpee muuttaa C:llä, silloin pitäisi C:ssä määritellä:

int omafunktio(char * Value);

ja vastaavasti Delphissä:

function omafunktio(Value:PChar):Integer; cdecl; external 'jokudll.dll';

tällöin annetaan C -funktion palauttaa uusi pituus (joka ei saa siltikään ylittää alkuperäistä pituutta!)

ja omafunktio -kutsu delphissä pitäisi tällöin tehdä näin:

UniqueString(St1);
SetLength(St1, omafunktio(PChar(St1)));

Näin siis C:ssä voi muuttaa merkkijonon sisältöä ja/tai lyhentää sitä, mutta EI pidentää.

Delphin String EI siis oikeasti ole PChar, mutta on suunniteltu siten, että sitä voi tietyin rajoituksin kohdella PChar:na, kunhan:

a) merkkijonoa ei muuteta PChar -viittauksen kautta

tai

b) UniqueString -kutsulla varmistetaan, että merkkijonon viitteiden määrä=1, tällöin sisältöä voi muuttaa, pituutta ei.

Pituutta ei siis tule milloinkaan suoraan muuttaa PChar -viittauksen kautta, mutta toki PChar -viittauksen saava funktio voi palauttaa uuden (saman tai lyhyemmän pituuden kuin alkuper. pituus) pituuden, joka sitten Delphillä asetetaan voimaan SetLength -proseduurilla.

Huomaa myös:

St1 := 'abc'#0'def';

nyt:

length(St1) = 7,

mutta:

strlen(PChar(St1)) = 3

!!!

strlen(PChar(St1)) on yleensä sama kuin length(St1), mutta JOS St1 sisältää NULL -merkkejä eli #0 = chr(0) ( basicissa chr$(0) )

niin tällöin strlen ilmoittaa merkkien määrän ennen ensimmäistä null -merkkiä, mutta length merkkijonon koko pituuden null -merkkeineen.

Jos merkkijono voi sisältää NULL -merkkejä, tulee mahd. C -koodille välittää erikseen merkkijonon pituus kokonaislukuna, koska muuten C:ssä oletusarvoisesti ensimmäinen NULL katkaisee merkkijonon, Delphissä taas ei.

Huomaa: monet I/O -aliohjelmat (kuten windows MessageBox ja delphin omakin ShowMessage) tulkitsevat merkkijonon päättyvän NULL -merkkiin.

Näppärä toki koodaa tarvittaessa oman apufunktion, joka esim tekee merkkijonosta kopion siten, että NULL -merkin tilalle tuleekin merkkijono '' ...

0

318

    Vastaukset

    Anonyymi (Kirjaudu / Rekisteröidy)
    5000

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

      Luetuimmat keskustelut

      1. Purra sössi kaiken 2 vuodessa, itkee nyt Marinin perään

        Nyt on taas sama vanha itkuvirsi, kun ei omat taidot riittänee. Kaikki on taas muiden syytä. No miten sen "Tunnin juna"
        Maailman menoa
        89
        9299
      2. Ikuiset kaipaajat

        Miksette vaan mene sen kaipauksen kohteen luokse ja puhu sille suoraan? Mitä järkeä on kaipailla jotain puolituttua vuo
        Ikävä
        164
        5829
      3. Nyt se on selvitetty: Sanna Marinin hallitus lisäsi menoja 41 miljardilla

        ”vasemmistohallitus oli katastrofaalisen huono”, sanoo kokoomus. Sanna Marinin (sd.) hallituksen tekemät menolisäykset
        Maailman menoa
        147
        5172
      4. Eli persujen rääkyminen Marinin hallituksen velanotosta oli sitä itseään

        "Valtiovarainministeriön mukaan Marinin hallitus lisäsi valtion pysyviä menoja 3 miljardia eikä 11 miljardia euroa." El
        Maailman menoa
        12
        5013
      5. Orpon hallitus runnoi Tunnin junan ilman tarvetta

        Näinkö valtiontaloutta hoidetaan? Siis asiantuntijoidenkin aikoja sitten kannattamattomaksi laskema Tunnin juna tehdään
        Maailman menoa
        38
        4198
      6. Riikka ottaa miljardi euroa EU:n yhteisvelkaa Suomelle

        Niin kääntyi irvipersun takki taas, vaikka vaalilupauksissa oli ettei yhteisvelkaa Suomi enää koskaan ota. No nyt otti m
        Maailman menoa
        86
        3509
      7. Lindtman ylivoimainen suosikki pääministeriksi

        Lindtmania kannattaa pääministeriksi peräti 50 prosenttia useampi kuin toiseksi suosituinta Kaikkosta. https://www.ilta
        Maailman menoa
        58
        3444
      8. Sanna Marin - Maailman paras talousasiantuntija?

        PersKeKoa pukkaa? https://www.hs.fi/politiikka/art-2000011636623.html
        Maailman menoa
        110
        2831
      9. En tiedä ymmärrätkö

        Kuinka paljon merkitset mulle. Näet minut minuna etkä silti käännä selkääsi. Tökit jatkuvasti kepillä jäätä ja menit ehk
        Ikävä
        10
        2811
      10. Veronmaksajat kustantavat yrittäjien eläkkeitä jo yli 500 miljoonalla

        Suomalaista yrittäjää ei kommunistista erota. Aktiivisen "yrittämisen" maksattaa yritystukina yhteiskunnalla, ja vieläpä
        Yrittäjyys
        44
        2790
      Aihe