mixed-language programming / Linux

Joskus kahden eri ohjelmointikielen käyttö tuottaa yllättäviä tuloksia !

Tässä tapauksessa on c -kielellä tehty kirjasto (käännetty .so -kirjastoksi gcc:llä).

Pääohjelma on tehty FreePascal / Lazarus -yhdistelmällä.

Pääohjelma lataa tuon .so -kirjaston LoadLibrary ja hakee xmain -funktion osoitteen GetProcAddress -funktiolla.

FreePascal pyrkii tarjoamaan käyttöjärjestelmäriippumatont aohjelmointia niin pitkälle kuin mahdollista, niinpä nuo mainitut funktiot windowsissa ovat suoraan vastaavia winAPI -kutsuja, ja linuxissa ne ovat aliaksia dlopen() ja dlsym() -funktioille.

Tuo ohjelman ja .so:n yhdistelmä toimii oikein, kun antaa tulosten tulostua näytölle.

Sensijaan jos ohjelman ajaa näin:

ohjelma >lokitiedosto.txt

niin osa C -kielisen kirjaston tulosteista katoaa olemattomiin, ja lisäksi pääohjelman ja .so -kirjaston tulosteiden keskinäinen järjestys muuttuu yllättävästi!

C -kirjasto käyttää C:n kirjastofunktiota printf()

ja pääohjelma Objectpascalin Write ja WriteLn -proseduureja.

Ilmeisesti objectpascal -koodiin pitäisi lisätä jokin flush -kutsu ennen sellaisia .so -kirjastoon kohdistuvia funktiokutsuja, joiden sisällä tapahtuu printf() -kutsuja.

Ja vastaavasti ilmeisesti C -kielisissä funktioissa pitäisi kutsua jotakin flush -funktiota ennen paluuta (pääohjelmaan).

Muussa tapauksessa C -kielen stdout ja objectpascalin output -tiedostojen käsittely ilmeisesti jollain tavalla häritsevät toisiaan.

Eli: Mikä flush -kutsu ja miten sitä käytetään:

a) C -kielessä

ja

b) Objectpascalissa ?
9330
Äänestä

Muut lukivat myös

Vastaukset 9

Vanhimmat

vastaus / C-kieli

C -kielessä ongelma näköjään ratkeaa laittamalla jokaisen sellaisen pääohjelmasta kutsuttavan funktion viimeiseksi (juuri ennen return -lausetta) ohjelmakoodiriviksi tämä:

fflush(stdout);

joka (suoraan tai välillisesti) kutsuu printf() -funktiota siten, että tulostus menee standarditulostusvirtaan (stdout).

Objectpascalin osalta jää selvitettäväksi, tavitaanko vastaavaa toimenpidettä sielläkin, ja miten se siellä hoidetaan...

Äänestä
  • Flush:in käytöstä...

    Siis:

    mikä on itseasiassa oikea sääntö flush:in käytöstä?

    Käyttökohteena siis standarditulostevirta eli stdout (C) ja output (Objectpascal).

    Kerrottakoon sen verran, että alunperin on ollut C -kielinen ohjelma, jonka olen itse muuntanut .so -kirjastoksi ja sitten olen itse kirjoitanut FreePascal Lazarus -yhdistelmällä ohjelman, joka käyttää tätä .so -kirjastoa.

    Seuraavaksi olisi tarkoitus lisätä hyvin moneen kohtaan ko. C -koodia kutsu funktioon, joka on määritelty C:ssä funktiotyyppinä ja osoittimena funktioon, joka laitetaan osoittamaan FreePascalilla tehtyyn proseduuriin.

    Koska kyseessä on Objectpascalissa proseduuri, niin luonnollisesti sen C -prototyypissä funktion paluuarvo on void.

    funktio saa yhtenä argumenttina C-kääntäjän tarjoamana char* -tyyppisen viitteen, joka osoittaa AsciiZ -merkkijonoon, joka kertoo sen funktion nimen, josta käsin tätä apufunktiota kutsuttiin.

    Lisäksi tarkoitus on välittää objectpascal -ohjelman tietoon osoitin varsin moneen alunperin C -ohjelman sisäiseen muuttujaan. Objectpascal -ohjelma ei kuitenkaan muuta ko. osoittimien osoittamaa tietoa, vaan lähinnä pasiivisesti tarkkailee muuttujien arvon muuttumista eri vaiheissa C -koodin suoritusta.

    Kuitenkin, koska sekä alkuperäinen C -koodi että itse kirjoittamani objectpascal -koodi saattavat molemmat kirjoitella standardiin tulostusvirtaan, niin jotenkin pitäisi pitää huolta, etteivät sotke toisiaan.

    Äänestä

  • Koodaaja80 kirjoitti:

    Flush:in käytöstä...

    Siis:

    mikä on itseasiassa oikea sääntö flush:in käytöstä?

    Käyttökohteena siis standarditulostevirta eli stdout (C) ja output (Objectpascal).

    Kerrottakoon sen verran, että alunperin on ollut C -kielinen ohjelma, jonka olen itse muuntanut .so -kirjastoksi ja sitten olen itse kirjoitanut FreePascal Lazarus -yhdistelmällä ohjelman, joka käyttää tätä .so -kirjastoa.

    Seuraavaksi olisi tarkoitus lisätä hyvin moneen kohtaan ko. C -koodia kutsu funktioon, joka on määritelty C:ssä funktiotyyppinä ja osoittimena funktioon, joka laitetaan osoittamaan FreePascalilla tehtyyn proseduuriin.

    Koska kyseessä on Objectpascalissa proseduuri, niin luonnollisesti sen C -prototyypissä funktion paluuarvo on void.

    funktio saa yhtenä argumenttina C-kääntäjän tarjoamana char* -tyyppisen viitteen, joka osoittaa AsciiZ -merkkijonoon, joka kertoo sen funktion nimen, josta käsin tätä apufunktiota kutsuttiin.

    Lisäksi tarkoitus on välittää objectpascal -ohjelman tietoon osoitin varsin moneen alunperin C -ohjelman sisäiseen muuttujaan. Objectpascal -ohjelma ei kuitenkaan muuta ko. osoittimien osoittamaa tietoa, vaan lähinnä pasiivisesti tarkkailee muuttujien arvon muuttumista eri vaiheissa C -koodin suoritusta.

    Kuitenkin, koska sekä alkuperäinen C -koodi että itse kirjoittamani objectpascal -koodi saattavat molemmat kirjoitella standardiin tulostusvirtaan, niin jotenkin pitäisi pitää huolta, etteivät sotke toisiaan.

    Flush(Output);

    Äänestä

Oletko käyttänyt Lazarusta myös gcc:n kanssa?

Äänestä
  • "Oletko käyttänyt Lazarusta myös gcc:n kanssa?"

    Ei nyt sentään!

    Vaan siis gcc:llä on vain käännetty c -kielistä lähdekoodia .so -dynaamiseksi kirjastoksi ja sitten Freepascal lazarus -yhdistelmällä koodatgtu ohjelma, joka käyttää tuon .so:n tarjoamia aliohjelmia.

    Siis suoraan ei lazarus toimi gcc:n kanssa, mutta kaiken uuden koodaankin freepascalilla (Linux) tai Delphillä (Windows).

    C -kielen ainoa tarve tulee siitä, että C:llä on valtavasti valmiiksi tehtyä koodia.

    Mutta jos itse koodaan uutta, niin miksi koodaisin C:llä kun objectpascal on joka suhteessa helpompi ja monipuolisempi työväline.

    Äänestä

  • Koodaaja80 kirjoitti:

    "Oletko käyttänyt Lazarusta myös gcc:n kanssa?"

    Ei nyt sentään!

    Vaan siis gcc:llä on vain käännetty c -kielistä lähdekoodia .so -dynaamiseksi kirjastoksi ja sitten Freepascal lazarus -yhdistelmällä koodatgtu ohjelma, joka käyttää tuon .so:n tarjoamia aliohjelmia.

    Siis suoraan ei lazarus toimi gcc:n kanssa, mutta kaiken uuden koodaankin freepascalilla (Linux) tai Delphillä (Windows).

    C -kielen ainoa tarve tulee siitä, että C:llä on valtavasti valmiiksi tehtyä koodia.

    Mutta jos itse koodaan uutta, niin miksi koodaisin C:llä kun objectpascal on joka suhteessa helpompi ja monipuolisempi työväline.

    Huhujen mukaan Lazaruksen alla oleva kääntäjä
    voisi olla joku muukin kuin FPC!!!

    Äänestä

  • Koodaaja80 kirjoitti:

    "Oletko käyttänyt Lazarusta myös gcc:n kanssa?"

    Ei nyt sentään!

    Vaan siis gcc:llä on vain käännetty c -kielistä lähdekoodia .so -dynaamiseksi kirjastoksi ja sitten Freepascal lazarus -yhdistelmällä koodatgtu ohjelma, joka käyttää tuon .so:n tarjoamia aliohjelmia.

    Siis suoraan ei lazarus toimi gcc:n kanssa, mutta kaiken uuden koodaankin freepascalilla (Linux) tai Delphillä (Windows).

    C -kielen ainoa tarve tulee siitä, että C:llä on valtavasti valmiiksi tehtyä koodia.

    Mutta jos itse koodaan uutta, niin miksi koodaisin C:llä kun objectpascal on joka suhteessa helpompi ja monipuolisempi työväline.

    Kannattaisi ottaa yhteyttä noihin Lazaruksen tekijöihin (esim. englannin kieliselle keskustelupalstalle tms). Selvittää millaisella vaivalla tuo Lazarus ympäristö hoitaisi molemmat käännökset. Voi olla hyvinkin mahdollista että saat todella hyviä vinkkejä sieltä.

    Äänestä


Kommentoi aloitusta


Koodaaja80 kirjoitti:

Joskus kahden eri ohjelmointikielen käyttö tuottaa yllättäviä tuloksia !

Tässä tapauksessa on c -kielellä tehty kirjasto (käännetty .so -kirjastoksi gcc:llä).

Pääohjelma on tehty FreePascal / Lazarus -yhdistelmällä.

Pääohjelma lataa tuon .so -kirjaston LoadLibrary ja hakee xmain -funktion osoitteen GetProcAddress -funktiolla.

FreePascal pyrkii tarjoamaan käyttöjärjestelmäriippumatont aohjelmointia niin pitkälle kuin mahdollista, niinpä nuo mainitut funktiot windowsissa ovat suoraan vastaavia winAPI -kutsuja, ja linuxissa ne ovat aliaksia dlopen() ja dlsym() -funktioille.

Tuo ohjelman ja .so:n yhdistelmä toimii oikein, kun antaa tulosten tulostua näytölle.

Sensijaan jos ohjelman ajaa näin:

ohjelma >lokitiedosto.txt

niin osa C -kielisen kirjaston tulosteista katoaa olemattomiin, ja lisäksi pääohjelman ja .so -kirjaston tulosteiden keskinäinen järjestys muuttuu yllättävästi!

C -kirjasto käyttää C:n kirjastofunktiota printf()

ja pääohjelma Objectpascalin Write ja WriteLn -proseduureja.

Ilmeisesti objectpascal -koodiin pitäisi lisätä jokin flush -kutsu ennen sellaisia .so -kirjastoon kohdistuvia funktiokutsuja, joiden sisällä tapahtuu printf() -kutsuja.

Ja vastaavasti ilmeisesti C -kielisissä funktioissa pitäisi kutsua jotakin flush -funktiota ennen paluuta (pääohjelmaan).

Muussa tapauksessa C -kielen stdout ja objectpascalin output -tiedostojen käsittely ilmeisesti jollain tavalla häritsevät toisiaan.

Eli: Mikä flush -kutsu ja miten sitä käytetään:

a) C -kielessä

ja

b) Objectpascalissa ?

Anonyymi
5000

Ilmoita asiaton sisältö

  • Sisältää materiaalia, joka on loukkaavaa, herjaavaa, rasistista, uhkailevaa tai ahdistelevaa.

  • Materiaali sisältää nimiä, yhteystietoja tai muita henkilökohtaisia tietoja. Julkisuuden henkilöistä, julkisissa viroissa toimivista ihmisistä sekä yritysten vastuuhenkilöistä saa keskustella työhön liittyen. Myös yksityiselämään liittyvistä asioista voi keskustella siltä osin, kuin niistä on julkisesti kerrottu.

  • Sisältää lapsille haitallista tai heiltä kiellettyä materiaalia. Seksuaalinen sisältö on sallittua aiheeseen tarkoitetuilla palstoilla, joiden ikäraja on 18 vuotta.

  • Lainvastaista sisältöä voi olla mm. yksityiselämää loukkaavan tiedon levitys, kiihottaminen kansanryhmää vastaan, laiton uhkaaminen, alaikäisiin liittyvä seksuaalinen sisältö/grooming, petokset, identiteettivarkaudet, kunnianloukkaukset ja tekijänoikeusrikkomukset.

  • Sisältö ei liity palstan tai keskusteluketjun aiheeseen.

  • Viesti ei ole suomea tai ruotsia (pl. International Forums), se sisältää mainontaa, se sisältää tekijänoikeuksin suojattua materiaalia, se on massapostitus tai jokin muu syy.

Jaa keskustelu