Ask Your Question
2

Načtení struktury z binárního souboru

asked 2015-02-21 12:53:58 +0100

Greg gravatar image

Zdravím,

přepisuji Cčkový program vytvořený pro 32-bit Win XP, který převádí jeden binární formát na jiný. Ten formát se skládá z nějaké hlavičky a samotných dat. Autor původního programu načte přímo celou hlavičku do struktury, kterou na to má připravenou. Nějak takto:

ReadFile(ztex, &ZTexHeader, sizeof(ZTexHeader), &BytesRead, NULL);

Co si ale vzpomínám z PA1, tak velikost struktury nemusí vždy odpovídat součtu velikostí datových typů v ní (velikost datových typů ve struktuře si případně pohlídám). Jde to tedy takhle načíst nehledě na platformu?

edit retag flag offensive close delete

1 Answer

Sort by » oldest newest most voted
3

answered 2015-02-21 13:19:25 +0100

Josef Kokeš gravatar image

updated 2015-02-21 14:14:42 +0100

Ano, ale musíte si to pohlídat:

  • Velikost některých datových typů se může na různých platformách lišit (např. int býval původně 16bitový). Takže je potřeba použít takové datové typy, které mají velikost konstantní bez ohledu na platformu.
  • Je třeba vyřešit alignment jednotlivých elementů struktury. Problém je, že to je různé pro různé kompilátory (např. #pragma pack pro MSVC), a navíc některé platformy nemusí některá zarovnání vůbec podporovat (jestli si dobře vzpomínám, tak zejména RISCové architektury jsou na to náchylné). Ale ano, mělo by to jít vyřešit dost univerzálně.

Kromě toho samozřejmě můžete říct, "můj program je určený pro 32bitová Windows, jiné platformy mě nezajímají a 64bitovou verzi taky kompilovat nebudu" a zarovnání vyřešit na úrovni system requirements :-)

Ještě doplním jednu věc - u načítání dat tímto způsobem je potřeba hlídat i další věci, ne jen alignment. Podstatná je třeba endianness procesoru (když budu načítat 0x01, 0x02, 0x03, 0x04 jako 32bitový integer, tak mi to dá dost podstatně jiný výsledek na LSB i386 a na MSB 68000), reprezentace datových typů (nemusí všichni používat stejný formát desetinného čísla, nemusí všichni používat ASCII nebo Unicode) atd. atd. Bylo by čistší načíst si jeden binární blok a ten potom po bajtech rozebrat a zkonvertovat do podoby vhodné pro tu moji aktuálně používanou platformu. Ale málokdo to dělá, protože to je hodně práce a vesměs to nestojí za to - "když si to někdo bude chtít spustit na 16bitové Motorole, tak si tuhle část přepíše, proč bych to měl dělat já".

edit flag offensive delete publish link more

Comments

Jak jsem psal, velikost datových typů není problém. Tam si to pohlídám. Takže vlastně bez tuny maker/přepínačů pro překladače to vypnutí zarovnání není možné a je tedy jednodušší načíst tu strukturu postupně?

Greg ( 2015-02-21 13:34:38 +0100 )edit

Nejjednodušší je říct si, že 100% přenositelnost vám za tu námahu nestojí a udělat si akorát jeden #if, ve kterém porovnáte velikost struktury s očekávanou hodnotou a v případě rozdílu vyhodíte chybu (aby bylo zřejmé, že je třeba strukturu opravit pro tu platformu, na které to zrovna kompilujete). Protože upřímně řečeno, 100% přenositelnost je téměř vždy YAGNI.

Josef Kokeš ( 2015-02-21 14:13:28 +0100 )edit

ok, 100% přenositelnost také nepotřebuji. Chtěl jsem akorát, aby se ten program rozumně choval na 32/64 bitových verzích Win/Mac/Linux. Jinde postrádá smysl. Jinak díky za odpověď ;-).

Greg ( 2015-02-21 14:28:31 +0100 )edit

Your answer

Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

Add answer

[hide preview]

Question tools

Follow
1 follower

Stats

Asked: 2015-02-21 12:53:58 +0100

Seen: 245 times

Last updated: Feb 21 '15