Kopírování bytů – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Kopírování bytů – C / C++ – Fórum – Programujte.comKopírování bytů – C / C++ – Fórum – Programujte.com

 

oxidián0
Grafoman
16. 3. 2015   #1
-
0
-

 Jak předělat tuto funkci aby kopírovala byty zleva doprava? Jde to vůbec nebo se vždy kopírují bajty zprava doleva? Nebo to je podmíněno systémem?

void read4bytes(unsigned char ** pSourceStr, uint32_t* item)
{
  memcpy(item,*pSourceStr,4);
  *pSourceStr+=4;
}

Taky jsem to zkoušel převést:

*item = UINT32_SWAP_LE_BE_CONSTANT(*item);

a to krachlo, ne hned napoprvé ale pak to nakonec někde krachlo.

uint32_t UINT32_SWAP_LE_BE_CONSTANT(uint32_t val)
  {
  return ((uint32_t)
   (
    (((uint32_t) (val) & (uint32_t) 0x000000ffU) << 24) |
    (((uint32_t) (val) & (uint32_t) 0x0000ff00U) <<  8) |
    (((uint32_t) (val) & (uint32_t) 0x00ff0000U) >>  8) |
    (((uint32_t) (val) & (uint32_t) 0xff000000U) >> 24)
    )
  );
  }
Nahlásit jako SPAM
IP: 78.45.199.–
17. 3. 2015   #2
-
0
-

memcpy zkopíruje blok paměti 1 : 1. Takže v uint32_t jsou byty v paměti ve stejném pořadí jako ve zdrojovém bufferu. Problém vznikne při přečtení uint32_t jako čísla. Jak se obsah paměti pro uint32_t bude interpretovat závisí na endianitě. 

Vhodnější je uint32_t poskládat pomocí bitových operací b. posun vlevo a b. OR.

hu

Nahlásit jako SPAM
IP: 2001:67c:1222:800:14e2:e2...–
oxidián0
Grafoman
17. 3. 2015   #3
-
0
-

Kdysi se říkalo ráno moudřejší večera, tak jsem si na to rozpoměl, že to není tou funkcí, ale tím jak se to ukládá do cílové proměnné.

A jak mám detekovat jestli systém podporuje BE nebo LE? To swapovací makro odtud:

http://programujte.com/forum/vlakno/28847-jak-prevest-char-4-na-na-uint32-t/

mi nefungovalo, protože očekává integer a používám unsigned integer.

nebo mám použít toto?

unsigned int SwapUINTfromChars(unsigned char n[]) {

return( n[0] * 0x01000000 +

               n[1] * 0x010000 +

                   n[2] * 0x0100 +

                                 n[3]);

}
Nahlásit jako SPAM
IP: 78.45.199.–
17. 3. 2015   #4
-
0
-

nelámal bych si s tím hlavu: 

char buffer[4];
unsigned int cislo;

// buffer[0] jako LSB, buffer[3] jako MSB

cislo = (buffer[3] << 24) | (buffer[2] << 16) | (buffer[1] <<8) | buffer[0];

Překladač zoptimalizuje a byty nakopíruje do cislo v pořadí podle endianity. Jinak endianitu najdeš v nastavení projektu. Rozhodně bych se vyhýbal implementačně závislému kódu. Nikdy nevíš, koho a proč napadne zvolit jinou endianitu.

hu

Nahlásit jako SPAM
IP: 2001:67c:1222:800:14e2:e2...–
KIIV
~ Moderátor
+43
God of flame
17. 3. 2015   #5
-
0
-

Tak u makra zmen suffix L na UL a treba to pojede. Kazdopadne makro neocekava zadny typ, chyba musi byt mezi klavesnici a zidli...

Na endianitu jsou taky preddefinovane makra..

Prinejhorsim se da udelat:

uint32_t swap(const char * in) {
    uint32_t x;
    char * y = (char *)&x;
    y[0]=in[3];
    y[1]=in[2];
    y[2]=in[1];
    y[3]=in[0];
    return x;
}
Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
oxidián0
Grafoman
17. 3. 2015   #6
-
0
-

Ta funkce co jsem tu vkládal nás zmátla. Zdrojový typ potřebuju uint32_t ne char nebo unsigned char

Nahlásit jako SPAM
IP: 78.45.199.–
KIIV
~ Moderátor
+43
God of flame
17. 3. 2015   #7
-
0
-

neuveritelnej problem s pretypovanim:

 swap( (const char *)&uint)

Nahlásit jako SPAM
IP: 62.168.56.–
Program vždy dělá to co naprogramujete, ne to co chcete...
17. 3. 2015   #8
-
0
-

A cílový? Také uint32_t, ale s jiným pořadím bytů? Kromě přetypování ukazatele lze použít union a nebo opět bitové operace.

hu

Nahlásit jako SPAM
IP: 2001:67c:1222:800:14e2:e2...–
oxidián0
Grafoman
17. 3. 2015   #9
-
0
-

Makro mi nefunguje správně v čem je problém?


#define SwapEndiannessU32(n) ((n) << 24) | (((n) >> 8) & 0x00FF0000LU) | (((n) >> 8) & 0x0000FF00LU) | ((n) << 24)

*item = SwapEndiannessU32(*item);

0x64000007 -> 0x7640000 

Nahlásit jako SPAM
IP: 78.45.199.–
17. 3. 2015   #10
-
0
-

Opět ti unikají základy. Podívej se na to, co to makro dělá a jak.

hu

Nahlásit jako SPAM
IP: 2001:67c:1222:800:14e2:e2...–
oxidián0
Grafoman
17. 3. 2015   #11
-
0
-

   

#define SwapEndianness32(n) ( (((n) & 0x000000ff) << 24 ) | (((n) & 0x0000ff00) <<  8) | (((n) & 0x00ff0000) >>  8) | (((n) & 0xff000000) >> 24 ) )
#define SwapEndiannessU32(n) ( (((n) & 0x000000ffU) << 24 ) | (((n) & 0x0000ff00U) <<  8) | (((n) & 0x00ff0000U) >>  8) | (((n) & 0xff000000U) >> 24 ) )


Už mi to jede

Nahlásit jako SPAM
IP: 78.45.199.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 60 hostů

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý