C# Tips: How to tell if system is little endian or big endian?
来源:互联网 发布:淘宝异地发货违规吗 编辑:程序博客网 时间:2024/05/22 08:06
上回书说到,如果用C语言来判断系统的字节存储顺序 Little endian 和 Big endian ,函数如下:
#include <stdint.h> #include <stdio.h> #include <stdlib.h> union TestEndian_Unit { uint16_t value; uint8_t bytes[2]; }; /*! This function get endianness of current running environment. Return value: 0 -- Little endian 1 -- Big endian Exception 0xFF00 means error occurs. Reference: http://en.wikipedia.org/wiki/Endianness For example: x86, x86-64 and Windows on PowerPC use little endian; FreeBSD on PowerPC and SPARC use big endian. */ int IsBigEndian() { union TestEndian_Unit flag; flag.value = 0xFF00; if(flag.bytes[0] == 0x00 && flag.bytes[1] == 0xFF) { return 0; } else if(flag.bytes[0] == 0xFF && flag.bytes[1] == 0x00) { return 1; } else { fprintf(stderr, "Error occurs in function IsBigEndian().\n"); exit(0xFF00); } }
那么,如何用托管代码来进行同样的判断呢?
方法一、借助Marshal
代码如下:
// -----------------------------------------------------------------------// <copyright file="SystemInfo.cs" Author="Yaping Xin">// Helper class to get system information.// </copyright>// -----------------------------------------------------------------------namespace TestEndian{ using System; using System.Runtime.InteropServices; /// <summary> /// Helper class to get system information. /// </summary> public class SystemInfo { /// <summary> /// This function get endianness of current running environment. /// Return value: False -- Little endian /// True -- Big endian /// Reference: http://en.wikipedia.org/wiki/Endianness /// /// For example: x86, x86-64 and Windows on PowerPC use little endian; /// FreeBSD on PowerPC and SPARC use big endian. /// </summary> /// <returns>True indicates big endian.</returns> public static bool IsBigEndian() { const UInt16 value = 0xFF00; byte[] bytes = ToBytes(value); if (bytes[0] == 0x00 && bytes[1] == 0xFF) { return false; } else if (bytes[0] == 0xFF && bytes[1] == 0x00) { return true; } else { throw new ArithmeticException( "Error occurs while judge system endian."); } } /// <summary> /// Convert UInt16 value to byte[2] array. /// </summary> /// <param name="value">the UInt16 value</param> /// <returns>byte[2] array</returns> private static byte[] ToBytes(UInt16 value) { IntPtr buffer = Marshal.AllocHGlobal(2); try { Marshal.StructureToPtr(value, buffer, false); byte[] bytes = new byte[2]; Marshal.Copy(buffer, bytes, 0, 2); return bytes; } catch (Exception ex) { string message = string.Format( "Error occurs while converting {0} to byte[2] array.", value); throw new Exception(message, ex.InnerException); } finally { Marshal.FreeHGlobal(buffer); } } }}
方法二、用C#来模拟C的Union结构
文件列表:
- TestEndianUnit.cs
- SystemInfo.cs
TestEndianUnit.cs
// -----------------------------------------------------------------------// <copyright file="TestEndianUnit.cs" Author="Yaping Xin">// Union structure to test system Endianness.// </copyright>// -----------------------------------------------------------------------namespace TestEndian{ using System; using System.Runtime.InteropServices; /// <summary> /// Union structure to test system Endianness. /// The C union structure definition is as below: /// union TestEndian_Unit /// { /// uint16_t value; /// uint8_t bytes[2]; /// }; /// </summary> [StructLayout(LayoutKind.Explicit)] public struct TestEndianUnit { #region Data field /// <summary> /// Data field as TestEndian_Unit.value /// </summary> [FieldOffset(0)] public UInt16 Value; /// <summary> /// Data field as TestEndian_Unit.bytes[0] /// </summary> [FieldOffset(0)] public byte HByte; /// <summary> /// Data field as TestEndian_Unit.bytes[1] /// </summary> [FieldOffset(1)] public byte LByte; #endregion #region Initialization /// <summary> /// Initializes a new instance of the TestEndianUnit struct. /// </summary> /// <param name="value">union struct value</param> public TestEndianUnit(UInt16 value) { this.HByte = 0; this.LByte = 0; this.Value = value; } #endregion }}
SystemInfo.cs
// -----------------------------------------------------------------------// <copyright file="SystemInfo.cs" Author="Yaping Xin">// Helper class to get system information.// </copyright>// -----------------------------------------------------------------------namespace TestEndian{ using System; /// <summary> /// Helper class to get system information. /// </summary> public class SystemInfo { /// <summary> /// This function get endianness of current running environment. /// Return value: False -- Little endian /// True -- Big endian /// Reference: http://en.wikipedia.org/wiki/Endianness /// /// For example: x86, x86-64 and Windows on PowerPC use little endian; /// FreeBSD on PowerPC and SPARC use big endian. /// </summary> /// <returns>True indicates big endian.</returns> public static bool IsBigEndian() { TestEndianUnit unit = new TestEndianUnit(0xFF00); if (unit.HByte == 0x00 && unit.LByte == 0xFF) { return false; } else if (unit.HByte == 0xFF && unit.LByte == 0x00) { return true; } else { throw new ArithmeticException( "Error occurs while judge system endian."); } } }}
方法三、用C#来模拟C的Union结构(unsafe)
文件列表:
- TestEndianUnit.cs
- SystemInfo.cs
TestEndianUnit.cs
// -----------------------------------------------------------------------// <copyright file="TestEndianUnit.cs" Author="Yaping Xin">// Union structure to test system Endianness.// </copyright>// -----------------------------------------------------------------------namespace TestEndian{ using System; using System.Runtime.InteropServices; /// <summary> /// Union structure to test system Endianness. /// The C union structure definition is as below: /// union TestEndian_Unit /// { /// uint16_t value; /// uint8_t bytes[2]; /// }; /// </summary> [StructLayout(LayoutKind.Explicit)] public unsafe struct TestEndianUnit { #region Data field /// <summary> /// Data field as TestEndian_Unit.value /// </summary> [FieldOffset(0)] public UInt16 Value; /// <summary> /// Data field as TestEndian_Unit.bytes /// </summary> [FieldOffset(0)] public fixed byte Bytes[2]; #endregion #region Initialization /// <summary> /// Initializes a new instance of the TestEndianUnit struct. /// </summary> /// <param name="value">union struct value</param> public TestEndianUnit(UInt16 value) { this.Value = value; } #endregion }}
SystemInfo.cs
// -----------------------------------------------------------------------// <copyright file="SystemInfo.cs" Author="Yaping Xin">// Helper class to get system information.// </copyright>// -----------------------------------------------------------------------namespace TestEndian{ using System; /// <summary> /// Helper class to get system information. /// </summary> public class SystemInfo { /// <summary> /// This function get endianness of current running environment. /// Return value: False -- Little endian /// True -- Big endian /// Reference: http://en.wikipedia.org/wiki/Endianness /// /// For example: x86, x86-64 and Windows on PowerPC use little endian; /// FreeBSD on PowerPC and SPARC use big endian. /// </summary> /// <returns>True indicates big endian.</returns> public static unsafe bool IsBigEndian() { TestEndianUnit unit = new TestEndianUnit(0xFF00); if (unit.Bytes[0] == 0x00 && unit.Bytes[1] == 0xFF) { return false; } else if (unit.Bytes[0] == 0xFF && unit.Bytes[1] == 0x00) { return true; } else { throw new ArithmeticException( "Error occurs while judge system endian."); } } }}
需要注意的是:方法三的代码需要在Project中打开“unsafe”选项才可编译,如图:
参考文献:
- C Tips: How to tell if system is little endian or big endian? http://blog.csdn.net/xinyaping/article/details/7450920
- Endianness http://en.wikipedia.org/wiki/Endianness
- Big and Little Endian http://www.cs.umd.edu/class/sum2003/cmsc311/Notes/Data/endian.html
- C# Tips: How to tell if system is little endian or big endian?
- C Tips: How to tell if system is little endian or big endian?
- Big endian or Little endian
- Little-endian or Big-endian
- c big endian OR little endian
- Little endian & Big endian
- big-Endian&little-Endian
- big-Endian&little-Endian
- big-Endian&little-Endian
- little endian && big-endian
- Big endian & Little endian
- big-endian/little-endian
- Big endian Little endian
- Big-endian & Little-endian
- Little-endian & Big-endian
- big endian & little endian
- Big endian Little endian
- Little Endian, Big Endian
- tomcat theory
- jw player
- STM32红外的实现
- 从黑客到极客——hacker文化的演化
- hdu 3071 Gcd & Lcm game
- C# Tips: How to tell if system is little endian or big endian?
- Vector和ArrayList,LinkedList,Hashtable,HashMap的区别
- 使用 dom4j 解析 XML
- 改变键盘颜色
- 键盘大小改变的消息
- iPhone 手势识别
- Iphone代码片段导航
- ios 怎么判断当前的输入法
- Dom4j的使用(全而好的文章)