Kirjoitin C:llä yksinkertaisen demon jaetun muistin käytöstä. Kaikki netistä löytämäni demot oli kirjoitettu C++:lla ja niissä oli lähes poikkeuksetta graafisia käyttöliittymiä, joiden toteuttamiseen tarvittavien koodirivien varjoon demon kannalta oleellinen koodi jää. Graafinen käyttöliittymä on mielestäni hätävarjelun liioittelua, joten minun demossani ei ylimääräisiä rivejä ole.
Demo koostuu kolmesta ohjelmasta: SharedDataSegmentDLLHostingApplication, SharedDataValueIncrementer ja SharedDataValuePrinter. Jaetun muistialueen sekä sen manipulointiin tarvittavat funktiot sisältävä DLL on nimeltään SharedDataSegmentDLL.
SharedDataSegmentDLL
Kun käytetään GCC:tä, DLL:ään voidaan koodata jaettu kokonaislukumuuttuja seuraavasti:int sharedInteger __attribute__((section ("shared"), shared)) = 0;Microsoftin kääntäjä/linkitin haluaa nähdä rivit
#pragma data_seg (".shared")Tässä on siis määritelty kokonaisluku
int sharedInteger = 0;
#pragma data_seg()
#pragma comment(linker, "/SECTION:.shared,RWS")
sharedInteger
jaetuksi. Muuttuja on alustettava kuten yllä on esitetty. Muuttujan arvo voidaan lukea yksinkertaisesti tekemällä DLL:ään funktio PrintSharedDataValue()
:DLLEXPORT void PrintSharedDataValue() {Muuttujan arvoa voidaan muuttaa funktiolla
printf("%i", sharedInteger);
}
IncrementSharedDataValue()
:DLLEXPORT void IncrementSharedDataValue() {Tässä
sharedInteger++;
}
DLLEXPORT
on määritelty siten, että kääntäjä ymmärtää, että DLL:n lataavien prosessien on tarkoitus käyttää funktiota:#ifndef DLLEXPORTLisäksi tarvitaan funktio
#define DLLEXPORT __declspec(dllexport) // export DLL information
#endif
DLLSleep()
. Jos nimittäin HostingApplication kutsuisi vain Win32 API:n Sleep()
-funktiota, Windowsin lataimella ei olisi mitään syytä ladata SharedDataSegmentDLL:ää. Kun DLL:ään koodataan DLLSleep()
:DLLEXPORT void DLLSleep() {ja kutsutaan tätä funktiota HostingApplicationissa,
Sleep(INFINITE);
}
Windowsin on pakko ladata DLL. Tällöin jaettu muuttuja tulee samalla alustetuksi.
SharedDataSegmentDLLHostingApplication
Tämän ohjelman tarkoitus on pysyä käynnissä ja pitää SharedDataSegmentDLL ladattuna muistissa. Ohjelma on varsin yksinkertainen:
#include "../header/dll.h"
DLLIMPORT void DLLSleep();
int main(int argc, char *argv[])
{
DLLSleep();
}
DLLIMPORT
kertoo, että on tarkoitus käyttää DLL:ssä määriteltyä funktiota DLLSleep()
. DLLIMPORT
on määritelty tiedostossa dll.h. Muuta main()
-funktiossa ei sitten tarvitsekaan tehdä. SharedDataSegmentDLLHostingApplication nukkuu ikuisesti ja pitää DLL:n muistissa.SharedDataValueIncrementer
SharedDataValueIncrementer kasvattaa jaetun kokonaisluvun arvoa kutsumalla funktiota IncrementSharedDataValue():#include "../header/dll.h"
DLLIMPORT void IncrementSharedDataValue();
int main(int argc, char *argv[])
{
IncrementSharedDataValue();
}
SharedDataValuePrinter
SharedDataValuePrinter tulostaa jaetun kokonaislukumuuttujan arvon kutsumalla funktiotaPrintSharedDataValue()
#include "../header/dll.h"
DLLIMPORT void PrintSharedDataValue();
int main(int argc, char *argv[])
{
PrintSharedDataValue();
}
Ohjelmiston kääntäminen
Olen määritellyt dll.h:n sijainniksi ../header, jolloin jokainen lähdekooditiedosto sijaitsee omassa hakemistossaan ja dll.h header-hakemistossa. Lisäksi kääntäjää voi joutua neuvomaan etsimään otsaketiedostoja header-hakemistosta. DLL on käännettävä ensin, koska sitä tarvitaan ohjelmien kääntämiseksi. Kääntäjälle on kerrottava, että sen tulee käyttää DLL:ää vastaavaa lib-tiedostoa.Ohjelmiston käyttö
SharedDataDLLHostingApplication käynnistetään komentotulkista. Toisesta komentotulkista käytetään SharedDataValuePrinteriä ja SharedDataValueIncrementeriä, jonka pitäisi kasvattaa muuttujan arvoa yhdellä jokaisella ajokerralla. Jos muuttujan arvo ei muutu, muuttujan määrittely jaetuksi ei ole onnistunut. DLL:n pitää sijaita samassa hakemistossa kuin ohjelmat.Lähdekoodi
Lähdekoodia saa käyttää vapaasti.dll.h (teksti) (HTML)
SharedDataSegmentDLL.c (teksti) (HTML)
SharedDataSegmentDLLHostingApplication.c (teksti) (HTML)
SharedDataValueIncrementer.c (teksti) (HTML)
SharedDataValuePrinter.c (teksti) (HTML)
SharedDataSegmentDemoGCC.zip
Ei kommentteja:
Lähetä kommentti