No defined byte order for C#?

M

Michi Henning

Looking at the language spec, I can't find a statement
about the byte order for value types, such as int, float,
etc. Are they guaranteed to be little-endian or big-
endian? I know that, on a little-endian machine, the byte
order is little-endian. But what if I run C# on a big-
endian machine, say, using Mono?

Does the C# language (or IL) make any guarantees as to the
byte order?

Thanks,

Michi.
 
V

Vijaye Raji

It's the runtime that needs to take care of the endian issues. Not the
language by itself.

There are some implementations of the .Net runtime on Big Endian machines
and the same code compiles fine and runs on both machines (with special
attention to endian differences, of course)

-vJ
 
R

Rob Teixeira [MVP]

If you need to know, call BitConverter.IsLittleEndian.

-Rob Teixeira [MVP]
 
M

mikeb

Michi said:
Looking at the language spec, I can't find a statement
about the byte order for value types, such as int, float,
etc. Are they guaranteed to be little-endian or big-
endian? I know that, on a little-endian machine, the byte
order is little-endian. But what if I run C# on a big-
endian machine, say, using Mono?

Does the C# language (or IL) make any guarantees as to the
byte order?

No. But if you really need to know (which should be relatively rare)
you can use the Bitconverter.IsLittelEndian field to determine the
underlying architecture.

I assume that the other BitConverter methods would take the endianness
into account (it doesn't seem to be explicitly documented in the SDK),
to make converting blobs of bytes (in byte arrays) to .NET native types
easy.

On the down-side, as far as I can tell BitConverter is not part of the
ECMA CLI standard, so it might not exist on a Mono (or other non-MS)
runtime for all I know.
 
M

Michi Henning

Does the C# language (or IL) make any guarantees as to
the
No. But if you really need to know (which should be relatively rare)
you can use the Bitconverter.IsLittelEndian field to determine the
underlying architecture.

Ah, thanks. I'm unmarshaling a little-endian byte stream
and need to turn the data in the byte stream back into
real things, such as floats and ints. So, when I'm running
on a big-endian machine, I have to change the byte order
accordingly.

BitConverter is close to what I need. But, what do I do
when I'm running on a big-endian machine and need to
convert a little-endian byte stream? From what I can see,
there is no way to tell BitConverter what byte order the
array is in that is to be converted.

And, of course, I need to be able to do the opposite:
convert C# value types into a little-endian byte stream
(whether I'm running on a little-endian or big-endian
machine). Is there any class that does the inverse of what
BitConverter does?
I assume that the other BitConverter methods would take the endianness
into account (it doesn't seem to be explicitly documented in the SDK),
to make converting blobs of bytes (in byte arrays) to .NET native types
easy.

Well, as far as I can see, there is no way to specify the
byte order of the byte array.
On the down-side, as far as I can tell BitConverter is not part of the
ECMA CLI standard, so it might not exist on a Mono (or other non-MS)
runtime for all I know.

Aha. Thanks for pointing that out. I guess I can always
write it myself (but I don't see a way to do this without
having to resort to pointers and unsafe code.

What I'm really looking for is something along the lines
of java.nio.ByteBuffer.

Cheers,

Michi.
 
?

=?ISO-8859-1?Q?Carlos_Guzm=E1n_=C1lvarez?=

Hello:
And, of course, I need to be able to do the opposite:
convert C# value types into a little-endian byte stream
(whether I'm running on a little-endian or big-endian
machine).

Review :

IPAddress.HostToNetworkOrder

and

IPAddress.NetworkToHostOrder



Hope this helps.
 
J

Jon Skeet [C# MVP]

Michi Henning said:
BitConverter is close to what I need. But, what do I do
when I'm running on a big-endian machine and need to
convert a little-endian byte stream? From what I can see,
there is no way to tell BitConverter what byte order the
array is in that is to be converted.

No. It's a pain, isn't it?

I've considered before writing a version of BitConverter that lets you
specify the byte order, or fetch the default. Would you be interested
in such a class if I wrote it?
 
M

mikeb

Carlos said:
Hello:



Review :

IPAddress.HostToNetworkOrder

and

IPAddress.NetworkToHostOrder

Unfortunately for the original poster, Network Order is big-endian.

I think he'll need to write his own class based on BitConverter and/or
the IPAddress methods (or take Jon Skeet up on his offer).
 
M

Michi Henning

there is no way to tell BitConverter what byte order
the
No. It's a pain, isn't it?

I've considered before writing a version of BitConverter that lets you
specify the byte order, or fetch the default. Would you be interested
in such a class if I wrote it?

Absolutely! Bit converter really ought to be able to
convert between representations. And it should be
bidirectional, so I can convert from values to byte arrays
as well. (The introduction in the man page actually claims
that BitConverter can do this but, of course, the relevant
methods don't exist.)

Cheers,

Michi.
 
J

Jon Skeet [C# MVP]

Michi Henning said:
Absolutely! Bit converter really ought to be able to
convert between representations. And it should be
bidirectional, so I can convert from values to byte arrays
as well. (The introduction in the man page actually claims
that BitConverter can do this but, of course, the relevant
methods don't exist.)

Yes they do - BitConverter.GetBytes(char), BitConverter.GetBytes(int)
etc.
 
M

Michi Henning

(The introduction in the man page actually claims
Yes they do - BitConverter.GetBytes(char), BitConverter.GetBytes(int)
etc.

Ah, yes, thanks! Me blind... :-(

So, the only thing missing is being able to specify a byte
order for the array, so I can convert little-endian to big-
endian and vice versa.

Anyway, I wrote a class that is essentially identical to
java.nio.ByteBuffer, which does what I need.

Thanks for all the help!

Cheers,

Michi.
 
G

Guest

BTW, along the same lines - sending unicode strings over the network is going to be a pain too. Won't I need to convert every single character in the string using HostToNetworkOrder and then send out the resultiing buffer. Something along the lines of (its ugly and has no bounds checks)

int index = 0;
byte[] myBuffer = new byte[1024];
foreach (char c in myString)
{
byte[] hb = BitConverter.GetBytes(c);
short hs = BitConverter.ToInt16(hb, 0);
short ns = IPAddress.HostToNetworkOrder(hs);

byte[] nb = BitConverter.GetBytes(ns);
nb.CopyTo(myBuffer, index*2);
index++;
}

myNetworkStream.Write(myBuffer, 0, index*2);
 
J

Jon Skeet [C# MVP]

srikant said:
BTW, along the same lines - sending unicode strings over the network
is going to be a pain too. Won't I need to convert every single
character in the string using HostToNetworkOrder and then send out the
resultiing buffer. Something along the lines of (its ugly and has no
bounds checks)

int index = 0;
byte[] myBuffer = new byte[1024];
foreach (char c in myString)
{
byte[] hb = BitConverter.GetBytes(c);
short hs = BitConverter.ToInt16(hb, 0);
short ns = IPAddress.HostToNetworkOrder(hs);

byte[] nb = BitConverter.GetBytes(ns);
nb.CopyTo(myBuffer, index*2);
index++;
}

myNetworkStream.Write(myBuffer, 0, index*2);

This is exactly what Encodings are for - and getting the right encoding
(eg using Encoding.BigEndianUnicode or creating an instance of
UnicodeEncoding with the appropriate constructor) will do it all for
you.

(You also wouldn't need to use BitConverter in the above anyway - just
nb[index++]=(byte)(c>>8);
nb[index++]=(byte)(c&0xff);
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top