Klávesové zkratky na tomto webu - základní
Přeskočit hlavičku portálu


Programování pro PalmOS počítače krok za krokem (27)

aktualizováno 
Operační systém PalmOS - resp. jeho součást zvaná manažer paměti přiděluje naší aplikaci paměť v blocích. Tyto bloky mohou být buď nepřemístitelné (jejich počáteční adresa se nemění), nebo přemístitelné (jejich počáteční adresu předem neznáme, neboť ji manažer paměti může libovolně měnit).

3.5. Práce s nepřemístitelnými bloky paměti

Manipulace s nepřemístitelnými bloky je jednoduchá. Pomocí funkce MemPtrNew() požádáme operační systém o přidělení bloku paměti požadované velikosti. Pokud tato funkce vrátí adresu bloku paměti, byl v dynamické paměti inicializován nepřemístitelný blok paměti dané velikosti, patřící naší aplikaci, a tento blok můžeme okamžitě používat. Po skončení práce s blokem paměti jej musíme vrátit operačnímu systému voláním funkce MemPtrFree().

MemPtr MemPtrNew(UInt32 size)

Požadavek na přidělení bloku nepřemístitelné paměti zadané velikosti.

Vstupní parametry
  • size - velikost požadovaného bloku paměti v byte (musí být větší než nula a menší než přibližně 65400)
Vrácená hodnota
  • 0 - nepovedlo se blok dané velikosti inicializovat. Nejběžnější příčinou je nedostatek paměti.
  • ostatní hodnoty - adresa počátku nepřemístitelného bloku paměti, velikého size byte.

Vrátí-li funkce MemPtrNew() nenulovou hodnotu, bylo volání úspěšné a blok paměti můžeme používat. Datový typ MemPtr je definován podobně jako typ void* v jazyce C - jedná se o obecnou adresu v paměti.

Err MemPtrFree(MemPtr blok)

Vrátí přidělený blok paměti zpět operačnímu systému.

Vstupní parametry
  • blok - adresa počátku bloku paměti, který byl alokován voláním funkce MemPtrNew().
Vrácená hodnota
  • 0 - úspěch
  • ostatní hodnoty - kód chyby

Manažer paměti PalmOS udržuje přehled i o tom, kterým aplikacím jednotlivé bloky paměti patří. Pokud při ukončení aplikace zjistí, že tato aplikace operačnímu systému nevrátila všechny bloky paměti, tak zbývající bloky paměti uvolní pro potřeby dalších aplikací sám. Přesto však patří k dobrým zvyklostem programátorů vrátit na konci aplikace operačnímu systému všechny bloky paměti, které aplikace od systému získala.

UInt32 MemPtrSize(MemPtr blok)

Zjistí velikost nepřemístitelného bloku paměti.

Vstupní parametry
  • blok - adresa počátku nepřemístitelného bloku paměti
Vrácená hodnota
  • velikost nepřemístitelného bloku paměti

Pomocí funkce MemPtrSize() můžeme zjistit velikost nepřemístitelného bloku paměti, známe-li jeho adresu. Je tedy možné napsat například následující fragment programu, který vyplní celý blok střídavě nulami a jedničkami

MemPtr blok = MemPtrNew(DELKA_BLOKU);

for(i = 0; i < MemPtrSize(blok); i++) 
{
    ((Char*)blok)[i] = i & 0x01; 
}

...

MemPtrFree(blok);

Pokud si přejeme změnit velikost již získaného nepřemístitelného bloku paměti, můžeme použít funkci MemPtrResize(). Pokud si přejeme blok zvětšit, musíme počítat s tím, že se to nepodaří. Naopak pokud bloky paměti zmenšujeme, je tato funkce vždy úspěšná.

Err MemPtrResize(MemPtr blok, UInt32 newSize)

Změní velikost nepřemístitelného bloku paměti.

Vstupní parametry
  • blok - adresa nepřemístitelného bloku paměti
  • newSize - požadovaná nová velikost
Vrácená hodnota
  • O - operace proběhla úspěšně a blok paměti od adresy blok má nyní požadovanou velikost
  • jiná hodnota - kód chyby

Vrátí-li funkce MemPtrResize() nulovou hodnotu, tak byla velikost bloku úspěšně změněna. Na rozdíl od funkce realloc() jazyka C/C++ je původní adresa bloku, jehož velikost touto funkcí měníme, stále platná.

Pokud plánujeme v naší aplikaci používat bloky, jejichž velikost budeme měnit, je vhodnější používat bloky přemístitelné.

Typický příklad použití funkcí MemPtrNew() a MemPtrFree() pro získání velkého pole je v následujícím rámečku. Nesmíme nikdy zapomenout na kontrolu, zda je hodnota vrácená funkcí MemPtrNew() nenulová. S nedostatkem paměti a tedy nemožností alokovat blok paměti se na starších modelech počítačů Palm Pilot a kompatibilních můžeme setkat docela často.

UInt16* pole = (UInt16*)MemPtrNew(DELKA * sizeof(UInt16));

if(pole != NULL)
{
    pole[0] = pole[DELKA - 1] = 0;

    // ... použití bloku ...
	
    MemPtrFree((MemPtr)(pole));
}

3.6. Přemístitelné bloky paměti

V podmínkách omezeného množství paměti, které panují na počítačích Palm Pilot a kompatibilních, je výhodnější používat přemístitelné bloky paměti. Používání přemístitelných bloků paměti je z hlediska programátora o málo obtížnější, oproti tomu však tato technika umožní̈snížit nároky na paměť. Manažer paměti PalmOS optimalizuje využití paměti (uspořádává přemístitelné bloky v paměti dle aktuální potřeby) a dovolí měnit jejich velikost.

Žádáme-li systém o nepřemístitelný blok paměti, tak funkce MemPtrNew() vrátí přímo jeho adresu v paměti. Tento přístup u přemístitelných bloků zjevně nemůže fungovat, protože jejich adresa se může bez varování změnit. Místo toho používáme ovladače bloků paměti. Požadujeme-li od operačního systému blok přemístitelné paměti, tak manažer paměti tento blok vytvoří a vrátí ovladač bloku paměti (datový typ MemHandle).

Jak se však dostaneme k obsahu tohoto bloku paměti? Velmi jednoduše. Ve chvíli, kdy si přejeme z tohoto bloku číst nebo do něj zapisovat, tak jej uzamkneme na místě. Je-li přemístitelný blok paměti uzamčen na místě, tak jej manažer paměti po dobu uzamčení nemůže přemisťovat. Po skončení práce blok paměti odemkneme, tím opět dovolíme operačnímu systému tento blok posouvat po operační paměti.

Mnoho funkcí operačního systému vyžaduje jako parametry nebo vrací jako návratovou hodnotu právě ovladač bloku paměti, ve kterém jsou uložena požadovaná data.

MemHandle MemHandleNew(UInt32 size)

Vytvoří přemístitelný blok dynamické paměti a vrátí jeho ovladač.

Vstupní parametry
  • size - požadovaná velikost bloku paměti (větší než nula a menší než přibližně 65400
Vrácená hodnota
  • 0 - blok paměti se nepovedlo alokovat. Nejpravděpodobnější příčina je nedostatek paměti.
  • cokoliv jiného - ovladač bloku paměti.

Pomocí funkce MemHandleNew() vytvoříme v dynamické paměti přemístitelný blok, patřící naší aplikaci. Vrátí-li tato funkce nenulovou hodnotu, byl blok vytvořen úspěšně. Vzhledem k tomu, že nevíme, jaké bude množství dynamické paměti na počítači, na kterém naše aplikace poběží, musíme návratovou hodnotu této funkce vždy testovat, zda není rovna nule. Před použitím tohoto bloku paměti jej musíme uzamknout funkcí MemHandleLock() a po skončení používání jej musíme vrátit operačnímu systému voláním funkce MemHandleFree().

Err MemHandleFree(MemHandle ovladač)

Vrátí přemístitelný blok paměti zpět operačnímu systému.

Vstupní parametry
  • ovladač - ovladač bloku paměti, který vracíme operačnímu systému.
Vrácená hodnota
  • 0 - blok byl vrácen operačnímu systému
  • číslo chyby - byl předán neplatný ovladač bloku paměti

I u přemístitelných bloků platí, že bychom se měli snažit vrátit operačnímu systému všechny bloky paměti, které jsme získali. Pokud to neuděláme, tak operační systém (podobně jako u nepřemístitelných bloků paměti) po skončení naší aplikace automaticky zruší všechny zbývající bloky paměti, které aplikace vytvořila.

MemPtr MemHandleLock(MemHandle ovladač)

Uzamkne přemístitelný blok paměti na místě a vrátí jeho adresu.

Vstupní parametry
  • ovladač - ovladač bloku paměti, který uzamykáme.
Vrácená hodnota
  • 0 - nesprávný ovladač bloku paměti
  • jiná hodnota - adresa počátku bloku paměti, kterou můžeme používat pro zápis nebo čtení z bloku do okamžiku, kdy zavoláme funkci MemHandleUnlock().

Pomocí funkce MemHandleLock() můžeme blok uzamknout i opakovaně. Operační systém udržuje pro každý blok paměti hodnotu kolikrát byl uzamčen. Kdykoliv blok uzamkneme, tato hodnota se o jedničku zvýší a pokud blok odemkneme, tak se tato hodnota naopak sníží. Musíme si však pamatovat, že aby mohl operační systém s blokem zacházet (přemístit jej na jiné místo v paměti z důvodu optimalizace využití paměti), musíme jej odemknout (voláním funkce MemHandleUnlock()) právě tolikrát, kolikrát jsme jej uzamkli (počet uzamčení musí být roven nule).

Hodnota vrácená funkcí MemHandleLock() (typ MemPtr) může být bezpečně přetypována na libovolný ukazatel.

Err MemHandleUnlock(MemHandle ovladač)

Zruší uzamčení bloku paměti.

Vstupní parametry
  • ovladač - ovladač bloku paměti, který odemykáme.
Vrácená hodnota
  • 0 - uzamknutí bloku na místě bylo zrušeno
  • číslo chyby - byl předán neplatný ovladač bloku paměti

Funkce MemHandleLock() a MemHandleUnlock() nemění obsah bloku paměti. Tyto funkce pouze sdělují operačnímu systému, že si s blokem přejeme pracovat (MemHandleLock()) nebo že s blokem pracovat přestáváme (MemHandleUnlock()). Abychom mohli využít výhod přemístitelných bloků, musí být mezi uzamčením (voláním funkce MemHandleLock()) a odemčením (MemHandleUnlock()) co nejméně příkazů. Správné použití bloků paměti je v následujícím příkladu:

typedef struct
{
    UInt32 cislo;
    ...
} typBlokuPameti;

typBlokuPameti* blok;

MemHandle hText = MemHandleNew(sizeof(typBlokuPameti));

if(hText)
{
    // abychom mohli blok použít, musíme jej uzamknout na místě
    // teprve pak jej můžeme používat

    blok = (typBlokuPameti*)MemHandleLock(hText);
    blok->cislo = 0L;
    ....
    MemHandleUnlock(hText);

    // v tomto okamžiku již proměnná blok neobsahuje platnou adresu

	...

    // před čtením z bloku paměti jej opět musíme na chvíli
    // uzamknout na místě

    	
    blok = (typBlokuPameti*)MemHandleLock(hText);
    soucet += blok->cislo;
    ....
    MemHandleUnlock(hText);


    ...

    // Na konci musíme blok paměti vrátit operačnímu systému
	
    MemHandleFree(hText);
}

I u přemístitelných bloků paměti můžeme měnit jejich velikost pomocí funkce MemHandleResize(). Zmenšení velikosti proběhne vždy bezchybně. Důležité však je, že pokud si přejeme zvětšit velikost přiděleného bloku paměti, tak je mnohem pravděpodobnější, že se to podaří u přemístitelného bloku paměti (operační systém se jej pokusí přesunout do místa, kde může zvětšit jeho velikost).

Err MemHandleResize(MemHandle ovladač, UInt32 newSize)

Vstupní parametry
  • ovladač - ovladač bloku paměti, jehož velikost si přejeme změnit.
  • newSize - požadovaná nová velikost (větší než nula a menší než přibližně 65400)
Vrácená hodnota
  • O - operace proběhla úspěšně a blok paměti má nyní požadovanou velikost newSize byte
  • jiná hodnota - kód chyby

I u přemístitelných bloků paměti můžeme zjišťovat jejich velikost. Funkce, kterou se dotazujeme na velikost přemístitelného bloku paměti, se jmenuje MemHandleSize() a můžeme ji použít pro zjišťování velikosti uzamčeného i neuzamčeného bloku paměti.

UInt32 MemHandleSize(MemHandle ovladač)

Zjistí velikost přemístitelného bloku paměti.

Vstupní parametry
  • ovladač - ovladač bloku paměti, jehož velikost zjišťujeme.
Vrácená hodnota
  • velikost přemístitelného bloku paměti

Je užitečné si uvědomit, že uzamkneme-li přemístitelný blok paměti, tak se po dobu svého uzamčení (mezi voláním funkce MemHandleLock() a MemHandleUnlock()) chová úplně stejně jako nepřemístitelný blok paměti. Můžeme tedy například zjistit jeho velikost voláním funkce MemPtrSize().


V příštím díle dokončíme popis bloků paměti a povíme si o práci s řetězci v prostředí PalmOS.




Nejčtenější

Nový „levný“ iPhone má být hit. Prodat se ho má 100 milionů

Trojice iPhonů pro rok 2018

Apple chystá na letošní rok tři nové iPhony. Jedním z nich má být levnější model, který nebude mít OLED displej. A...

Nepoužívejte smartphony Huawei a ZTE, varují Američany FBI, CIA i NSA

Huawei Mate 10 Pro bude v USA k dostání u BestBuy

Huawei chtěl letos vzít útokem Spojené státy, a to s pomocí tamních klíčových operátorů. Z možné dohody však nakonec...



Teď přijde řada na naše peníze. V Číně totiž končí zlaté časy

Xiaomi Mi 6

Čínský trh s chytrými telefony je největší na světě, ale loni se podle všeho dostal do potíží. Po letech růstu přišel...

Lidé si stěžovali na špatný signál. Rušil ho těžař bitcoinů

(Ilustrační snímek)

Newyorští zákazníci amerického operátora T-Mobile si stěžovali na znatelný šum během telefonních hovorů. Ukázalo se, že...

Vše, co od smartphonu očekáváte, jen za 6 000. Test Honor 9 Lite

Honor 9 Lite

Honor 9 Lite je žhavou novinkou na českém trhu a také je potenciálním prodejním hitem. Smartphone s moderními funkcemi...

Další z rubriky

S těmito aplikacemi se o dovolené neztratíte. Najdou let i levný hotel

Ilustrační snímek

Místo slovníku, mapy a průvodce už řada lidí vyráží na dovolenou na neznámé místo jen se svým telefonem. V mnoha...

Záchranku volejte přes aplikaci. Pomoc je rychlejší než při volání na 155

Simulovaná dopravní nehoda jako praktická ukázka fungování mobilní aplikace...

„Záchranná služba, tísňová linka, dobrý den,“ ohlašuje se operátorka volajícímu, který se stal svědkem dopravní nehody....

Bez reklamy ani ránu. Bude už i na Facebook Messengeru v mobilu

Mobilní Messenger projde změnou, k nelibosti uživatelů v něm budou cílené...

Oblíbený mobilní kecálek se brzy promění. Facebook totiž do Messengeru po úspěšném testování implementuje cílené...



Najdete na iDNES.cz