Connecting Tech Pros Worldwide Forums | Help | Site Map

How to swap bytes in variables (VS2005)???

Bo Berglund
Guest
 
Posts: n/a
#1: Apr 7 '07
Preamble:
I am a Delphi (Pascal) programmer who has stumbled into the C++ world
by necessity since Borland has no 64 bit compiler yet out....
I used to do a lot of ANSI C programming for embedded systems about 15
years or so back, but since I started to do Windows programs I have
been using VB at first and then Delphi.

Problem:
When I communicate with embedded systems quite often the data are read
as binary streams and I have to compensate for the backwords storage
problem (Intel vs Motorola).
So in Delphi I have used the built-in Swap() function for reversing
the bytes in a 2-byte variable like an "unsigned short int" or "word"
in Pascal. I also have built a Swap32 function to handle 4-byte swaps.
Now I need to get this to work in C++ and I am getting errors all over
the place. Help appreciated.
Here is my code:

1. I have declared two struct type as follows:

typedef struct mytag16 {
unsigned char C1;
unsigned char C2;
}Reverse16;

typedef struct mytag32 {
unsigned char C1;
unsigned char C2;
unsigned char C3;
unsigned char C4;
}Reverse32;

It took a while to realize that the ANSI C declaration is different
(the name of the type goes before the braces and nothing comes after).

2. I am using these types in two functions to reverse the byte orders:

unsigned short Swap(unsigned short Source)
// Swap high and low chars of 16 bit word value
{
Reverse16 Tmp, Tmp2;
unsigned short Result;

Tmp = (Reverse16)Source;
Tmp2 = Tmp;
Tmp.C1 = Tmp.C2;
Tmp.C2 = Tmp2.C1;
Result = (unsigned short)Tmp;
return (Result);
}

and

void Swap32(*Source, bool bFlip)
// Swap high and low word of 32 bit source. If bFlip also swap whole
words
{
Reverse32 Tmp, Tmp2;

Tmp = (Reverse32)Source;
Tmp2 = Tmp;
if (bFlip)
{
Tmp.C1 = Tmp.C4;
Tmp.C2 = Tmp.C3;
Tmp.C3 = Tmp2.C2;
Tmp.C4 = Tmp2.C1;
}
else
{
Tmp.C1 = Tmp.C2;
Tmp.C2 = Tmp2.C1;
Tmp.C3 = Tmp.C4;
Tmp.C4 = Tmp2.C3;
}
Source = Tmp;
}

When i build the project I get a lot of errors like this:

1>..\..\..\Tests\AGI\TestAGI.cpp(82) : error C2440: 'type cast' :
cannot convert from 'unsigned short' to 'Reverse16'
1 No constructor could take the source type, or constructor
overload resolution was ambiguous

1>..\..\..\SentinelTests\AGI\SentinelAGI.cpp(83) : error C2440: 'type
cast' : cannot convert from 'unsigned short' to 'Reverse16'
1 No constructor could take the source type, or constructor
overload resolution was ambiguous

Apparently my typecast is not working, but why???
The structs are 2- and 4-bytes and the variables I am casting are also
2- and 4-bytes, so why does it not work?

And is there some built-in function I can use in place of my own to
reverse the byte orders?

/Bo


Bo Berglund
bo.berglund(at)nospam.telia.com

David Lowndes
Guest
 
Posts: n/a
#2: Apr 7 '07

re: How to swap bytes in variables (VS2005)???


>When i build the project I get a lot of errors like this:
Quote:
>
>1>..\..\..\Tests\AGI\TestAGI.cpp(82) : error C2440: 'type cast' :
>cannot convert from 'unsigned short' to 'Reverse16'
>...
>Apparently my typecast is not working, but why?
>The structs are 2- and 4-bytes and the variables I am casting are also
>2- and 4-bytes, so why does it not work?
You have to be a bit more devious - use pointers to the variables,
cast the pointers to pointers to the desired types, then dereference
the pointers. In C++ it's also safest to use the newer casts too -
static_cast<>().

Alternatively, use a union.
Quote:
>And is there some built-in function I can use in place of my own to
>reverse the byte orders?
Have you seen the _swab() function?

Dave
Nathan Mates
Guest
 
Posts: n/a
#3: Apr 7 '07

re: How to swap bytes in variables (VS2005)???


In article <nvte139ulmkj28f237hh70gh658216dui0@4ax.com>,
Bo Berglund <bo.berglundxxwrote:
Quote:
>So in Delphi I have used the built-in Swap() function for reversing
>the bytes in a 2-byte variable like an "unsigned short int" or
>"word" in Pascal. I also have built a Swap32 function to handle
>4-byte swaps. Now I need to get this to work in C++ and I am
>getting errors all over the place. Help appreciated.
You used a bunch of structs, which is a bit of overkill. C/C++ give
you access to bitshift operators, which allow you to directly pick and
move bits around. Your functions can be rewritten as:

unsigned short Swap16(unsigned short v)
{
return ((v & 0xFF) << 8) |
((v >8) & 0xFF);
}


unsigned long Swap32(unsigned long v)
{
return ((v & 0xFF) << 24) |
(((v >8) & 0xFF) << 16) |
(((v >16) & 0xFF) << 8) |
(((v >24) & 0xFF);
}

Nathan Mates
--
<*Nathan Mates - personal webpage http://www.visi.com/~nathan/
# Programmer at Pandemic Studios -- http://www.pandemicstudios.com/
# NOT speaking for Pandemic Studios. "Care not what the neighbors
# think. What are the facts, and to how many decimal places?" -R.A. Heinlein
Nathan Mates
Guest
 
Posts: n/a
#4: Apr 7 '07

re: How to swap bytes in variables (VS2005)???


In article <131fh801hhr46cf@corp.supernews.com>,
Nathan Mates <nathan@visi.comwrote:
Quote:
>unsigned short Swap16(unsigned short v)
>{
return ((v & 0xFF) << 8) |
((v >8) & 0xFF);
>}
Hm. I shouldn't post before I'm fully awake. The functions I posted
can be slightly optimized and/or clarified a bit better.

unsigned short Swap16(unsigned short v)
{
return ((v & 0x00FF) << 8) |
((v & 0xFF00) >8);
}


unsigned long Swap32(unsigned long v)
{
return ((v & 0x000000FF) << 24) |
((v & 0x0000FF00) << 8) |
((v & 0x00FF0000) > 8) |
((v & 0xFF000000) >24);
}

Nathan Mates
--
<*Nathan Mates - personal webpage http://www.visi.com/~nathan/
# Programmer at Pandemic Studios -- http://www.pandemicstudios.com/
# NOT speaking for Pandemic Studios. "Care not what the neighbors
# think. What are the facts, and to how many decimal places?" -R.A. Heinlein
Bo Berglund
Guest
 
Posts: n/a
#5: Apr 7 '07

re: How to swap bytes in variables (VS2005)???


On Sat, 07 Apr 2007 18:10:29 -0000, nathan@visi.com (Nathan Mates)
wrote:
Quote:
>In article <131fh801hhr46cf@corp.supernews.com>,
>Nathan Mates <nathan@visi.comwrote:
Quote:
>>unsigned short Swap16(unsigned short v)
>>{
> return ((v & 0xFF) << 8) |
> ((v >8) & 0xFF);
>>}
>
Hm. I shouldn't post before I'm fully awake. The functions I posted
>can be slightly optimized and/or clarified a bit better.
>
>unsigned short Swap16(unsigned short v)
>{
return ((v & 0x00FF) << 8) |
((v & 0xFF00) >8);
>}
>
>
>unsigned long Swap32(unsigned long v)
>{
return ((v & 0x000000FF) << 24) |
((v & 0x0000FF00) << 8) |
((v & 0x00FF0000) > 8) |
((v & 0xFF000000) >24);
>}
>
>Nathan Mates
Thanks!
That brought down my error count from 36 to 22...

Bo Berglund
bo.berglund(at)nospam.telia.com
Ben Voigt
Guest
 
Posts: n/a
#6: Apr 9 '07

re: How to swap bytes in variables (VS2005)???



"Bo Berglund" <boberglund@home.sewrote in message
news:350g13daangltpn36v0hge8avecssjjecu@4ax.com...
Quote:
On Sat, 07 Apr 2007 18:10:29 -0000, nathan@visi.com (Nathan Mates)
wrote:
>
Quote:
>>In article <131fh801hhr46cf@corp.supernews.com>,
>>Nathan Mates <nathan@visi.comwrote:
Quote:
>>>unsigned short Swap16(unsigned short v)
>>>{
>> return ((v & 0xFF) << 8) |
>> ((v >8) & 0xFF);
>>>}
>>
> Hm. I shouldn't post before I'm fully awake. The functions I posted
>>can be slightly optimized and/or clarified a bit better.
>>
>>unsigned short Swap16(unsigned short v)
>>{
> return ((v & 0x00FF) << 8) |
> ((v & 0xFF00) >8);
>>}
>>
>>
>>unsigned long Swap32(unsigned long v)
>>{
> return ((v & 0x000000FF) << 24) |
> ((v & 0x0000FF00) << 8) |
> ((v & 0x00FF0000) > 8) |
> ((v & 0xFF000000) >24);
>>}
If you know your data is in network byte order, then use htons and htonl
functions. They will do the byte swapping on Intel, but if you ever
compiled your code on an ARM or Alpha or whatever, they'll still do the
right thing.
Quote:
Quote:
>>
>>Nathan Mates
>
Thanks!
That brought down my error count from 36 to 22...
>
Bo Berglund
bo.berglund(at)nospam.telia.com

Closed Thread