Problem casting a byte[] to a class

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • O.B.

    Problem casting a byte[] to a class

    I'm trying to do a static_cast at runtime in C# and as I understand it,
    "as" is the keyword to use. Unfortunately, the compiler is trying to do
    the cast a compilation time. See below.

    /* TestA.cs */
    namespace TEST {
    class TestA {
    public ushort val1;
    public ushort val2;
    public ushort val3;
    }
    }

    /* Main Program */
    namespace TEST {
    class Program {
    static void Main(string[] args) {
    TestA test = null;
    byte[] testArray = new byte[6];
    for (int i = 0; i < testArray.Lengt h; i++) {
    testArray[i] = (byte)(i + 1);
    }
    // Trying to do a C++-style static_cast
    // Compilation error:
    // Cannot convert type 'byte[]' to 'TEST.TestA'
    // via a built-in conversion
    test = testArray as TestA;
    }
    }
    }

    What am I doing wrong?
  • John J. Hughes II

    #2
    Re: Problem casting a byte[] to a class

    Your assuming the data is sequentially stored and no other data exist in the
    class, both assumptions are incorrect.

    Normally you can serialize your class and desterilized but if the data needs
    to be in a compact byte array which I have found need for several times you
    will need to parse the data manually. I think you can overload the
    serialization function but I have found the below simpler.

    class TestA {
    public ushort val1;
    public ushort val2;
    public ushort val3;

    public TestA(byte[] data)
    {
    val1 = BitConverter.To UInt16(0);
    val2 = BitConverter.To UInt16(2);
    val3 = BitConverter.To UInt16(4);
    }
    public ToArray
    {
    get {
    MemoryStream ms = new MemoryStream();
    ms.Wirte(BitCon verter.GetBytes (val1, 0, 2);
    ms.Wirte(BitCon verter.GetBytes (val2, 0, 2);
    ms.Wirte(BitCon verter.GetBytes (val3, 0, 2);
    ms.Capacity = ms.Length;
    return ms.ToArray();
    }
    }
    }

    Regards,
    John

    "O.B." <funkjunk@bells outh.netwrote in message
    news:12jq3gr598 l2u1b@corp.supe rnews.com...
    I'm trying to do a static_cast at runtime in C# and as I understand it,
    "as" is the keyword to use. Unfortunately, the compiler is trying to do
    the cast a compilation time. See below.
    >
    /* TestA.cs */
    namespace TEST {
    class TestA {
    public ushort val1;
    public ushort val2;
    public ushort val3;
    }
    }
    >
    /* Main Program */
    namespace TEST {
    class Program {
    static void Main(string[] args) {
    TestA test = null;
    byte[] testArray = new byte[6];
    for (int i = 0; i < testArray.Lengt h; i++) {
    testArray[i] = (byte)(i + 1);
    }
    // Trying to do a C++-style static_cast
    // Compilation error:
    // Cannot convert type 'byte[]' to 'TEST.TestA'
    // via a built-in conversion
    test = testArray as TestA;
    }
    }
    }
    >
    What am I doing wrong?

    Comment

    • Jon Skeet [C# MVP]

      #3
      Re: Problem casting a byte[] to a class

      O.B. <funkjunk@bells outh.netwrote:
      I'm trying to do a static_cast at runtime in C# and as I understand it,
      "as" is the keyword to use. Unfortunately, the compiler is trying to do
      the cast a compilation time. See below.
      You can't do that in C# (thank goodness, IMO). You should either look
      at serialization, or add a method to TestA to convert an array of bytes
      (or a stream) into an instance of TestA.

      --
      Jon Skeet - <skeet@pobox.co m>
      http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
      If replying to the group, please do not mail me too

      Comment

      • John J. Hughes II

        #4
        Re: Problem casting a byte[] to a class

        Oh by the way if you convert to a structure and set the offsets manually you
        can then do a memory copy to accomplish what you did in C.

        Sort of like this, don't do it as often so a little fuzzer on how.

        [StructLayout(La youtKind.Explic it)]
        public struct TestA
        {
        [FieldOffset(0)] public ushort Val1;
        [FieldOffset(2)] public ushort Val2;
        [FieldOffset(4)] public ushort Val2;
        }

        Marshal.Copy(Da ta, 0, IntPtr <TestA>, 6);

        Regards,
        John

        "O.B." <funkjunk@bells outh.netwrote in message
        news:12jq3gr598 l2u1b@corp.supe rnews.com...
        I'm trying to do a static_cast at runtime in C# and as I understand it,
        "as" is the keyword to use. Unfortunately, the compiler is trying to do
        the cast a compilation time. See below.
        >
        /* TestA.cs */
        namespace TEST {
        class TestA {
        public ushort val1;
        public ushort val2;
        public ushort val3;
        }
        }
        >
        /* Main Program */
        namespace TEST {
        class Program {
        static void Main(string[] args) {
        TestA test = null;
        byte[] testArray = new byte[6];
        for (int i = 0; i < testArray.Lengt h; i++) {
        testArray[i] = (byte)(i + 1);
        }
        // Trying to do a C++-style static_cast
        // Compilation error:
        // Cannot convert type 'byte[]' to 'TEST.TestA'
        // via a built-in conversion
        test = testArray as TestA;
        }
        }
        }
        >
        What am I doing wrong?

        Comment

        • Jon Skeet [C# MVP]

          #5
          Re: Problem casting a byte[] to a class

          John J. Hughes II <no@invalid.com wrote:
          Your assuming the data is sequentially stored and no other data exist in the
          class, both assumptions are incorrect.
          >
          Normally you can serialize your class and desterilized but if the data needs
          to be in a compact byte array which I have found need for several times you
          will need to parse the data manually. I think you can overload the
          serialization function but I have found the below simpler.
          Note that for your solution, the line

          ms.Capacity = ms.Length;

          is unnecessary.

          Personally, I'd prefer to create the 6 byte array to start with, and
          then populate it. The "standard" BitConverter doesn't have any way to
          convert into the middle of an existing array, but my own one does :)

          See http://www.pobox.com/~skeet/csharp/miscutil and the
          EndianBitConver ter class.

          In this case, the code might be (converting it to a method rather than
          a property);

          public byte[] ToArray()
          {
          EndianBitConver ter converter = EndianBitConver ter.Little;
          byte[] ret = new byte[6];
          converter.CopyB ytes (val1, ret, 0);
          converter.CopyB ytes (val2, ret, 2);
          converter.CopyB ytes (val3, ret, 4);
          return ret;
          }

          --
          Jon Skeet - <skeet@pobox.co m>
          http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
          If replying to the group, please do not mail me too

          Comment

          • O.B.

            #6
            Re: Problem casting a byte[] to a class

            Actually, the code is bit more complex than what I posted. I'm reading
            data off of socket. In C++, I used a static_cast to cast the data to a
            union. In C#, I have used StructLayout and FieldOffset to acquire the
            "union" behavior. I just need the ability to overlay a structure
            (perhaps better than a class for this use case) on top of that byte array.

            The problem that I have with "as" when I use a struct is the following
            error:
            The as operator must be used with a reference type ('TEST.TestA' is a
            value type)

            Also, I really can't do an assignment on a per attribute basis. The
            data received over the socket is in big endian. I prefer to store it in
            big-endian and not waste any CPU cycles to convert it to little endian
            (speed is key in this application). The implicit and explicit operators
            are overridden to query header information from the data received. The
            data is then forwarded over many other socket connections in big-endian
            format; thus no byte-swapping conversions are required for the majority
            of the received data.

            Is there no way in C# to map a struct directly on top of a block of memory?



            John J. Hughes II wrote:
            Your assuming the data is sequentially stored and no other data exist in the
            class, both assumptions are incorrect.
            >
            Normally you can serialize your class and desterilized but if the data needs
            to be in a compact byte array which I have found need for several times you
            will need to parse the data manually. I think you can overload the
            serialization function but I have found the below simpler.
            >
            class TestA {
            public ushort val1;
            public ushort val2;
            public ushort val3;
            >
            public TestA(byte[] data)
            {
            val1 = BitConverter.To UInt16(0);
            val2 = BitConverter.To UInt16(2);
            val3 = BitConverter.To UInt16(4);
            }
            public ToArray
            {
            get {
            MemoryStream ms = new MemoryStream();
            ms.Wirte(BitCon verter.GetBytes (val1, 0, 2);
            ms.Wirte(BitCon verter.GetBytes (val2, 0, 2);
            ms.Wirte(BitCon verter.GetBytes (val3, 0, 2);
            ms.Capacity = ms.Length;
            return ms.ToArray();
            }
            }
            }
            >
            Regards,
            John
            >
            "O.B." <funkjunk@bells outh.netwrote in message
            news:12jq3gr598 l2u1b@corp.supe rnews.com...
            >I'm trying to do a static_cast at runtime in C# and as I understand it,
            >"as" is the keyword to use. Unfortunately, the compiler is trying to do
            >the cast a compilation time. See below.
            >>
            >/* TestA.cs */
            >namespace TEST {
            > class TestA {
            > public ushort val1;
            > public ushort val2;
            > public ushort val3;
            > }
            >}
            >>
            >/* Main Program */
            >namespace TEST {
            > class Program {
            > static void Main(string[] args) {
            > TestA test = null;
            > byte[] testArray = new byte[6];
            > for (int i = 0; i < testArray.Lengt h; i++) {
            > testArray[i] = (byte)(i + 1);
            > }
            > // Trying to do a C++-style static_cast
            > // Compilation error:
            > // Cannot convert type 'byte[]' to 'TEST.TestA'
            > // via a built-in conversion
            > test = testArray as TestA;
            > }
            > }
            >}
            >>
            >What am I doing wrong?
            >
            >

            Comment

            • O.B.

              #7
              Re: Problem casting a byte[] to a class

              This is *real* close to what I want. The only drawback is that I'm
              having to instantiate new memory for the TestA structure before calling
              Marshal. The UdpClient is already returning an allocated byte array.
              This application has to run as close to real-time as possible.

              TestA test;
              byte[] testArray = new byte[6];
              for (int i = 0; i < testArray.Lengt h; i++) {
              testArray[i] = (byte)(i + 1);
              }
              Marshal.Copy(te stArray, 0, (IntPtr)(&test) , 6);



              John J. Hughes II wrote:
              Oh by the way if you convert to a structure and set the offsets manually you
              can then do a memory copy to accomplish what you did in C.
              >
              Sort of like this, don't do it as often so a little fuzzer on how.
              >
              [StructLayout(La youtKind.Explic it)]
              public struct TestA
              {
              [FieldOffset(0)] public ushort Val1;
              [FieldOffset(2)] public ushort Val2;
              [FieldOffset(4)] public ushort Val2;
              }
              >
              Marshal.Copy(Da ta, 0, IntPtr <TestA>, 6);
              >
              Regards,
              John
              >
              "O.B." <funkjunk@bells outh.netwrote in message
              news:12jq3gr598 l2u1b@corp.supe rnews.com...
              >I'm trying to do a static_cast at runtime in C# and as I understand it,
              >"as" is the keyword to use. Unfortunately, the compiler is trying to do
              >the cast a compilation time. See below.
              >>
              >/* TestA.cs */
              >namespace TEST {
              > class TestA {
              > public ushort val1;
              > public ushort val2;
              > public ushort val3;
              > }
              >}
              >>
              >/* Main Program */
              >namespace TEST {
              > class Program {
              > static void Main(string[] args) {
              > TestA test = null;
              > byte[] testArray = new byte[6];
              > for (int i = 0; i < testArray.Lengt h; i++) {
              > testArray[i] = (byte)(i + 1);
              > }
              > // Trying to do a C++-style static_cast
              > // Compilation error:
              > // Cannot convert type 'byte[]' to 'TEST.TestA'
              > // via a built-in conversion
              > test = testArray as TestA;
              > }
              > }
              >}
              >>
              >What am I doing wrong?
              >
              >

              Comment

              • John J. Hughes II

                #8
                Re: Problem casting a byte[] to a class

                See my other post with [StructLayout(La youtKind.Explic it)] and Marshal.Copy.

                Regards,
                John

                "O.B." <funkjunk@bells outh.netwrote in message
                news:12jq617hqe tn834@corp.supe rnews.com...
                Actually, the code is bit more complex than what I posted. I'm reading
                data off of socket. In C++, I used a static_cast to cast the data to a
                union. In C#, I have used StructLayout and FieldOffset to acquire the
                "union" behavior. I just need the ability to overlay a structure (perhaps
                better than a class for this use case) on top of that byte array.
                >
                The problem that I have with "as" when I use a struct is the following
                error:
                The as operator must be used with a reference type ('TEST.TestA' is a
                value type)
                >
                Also, I really can't do an assignment on a per attribute basis. The data
                received over the socket is in big endian. I prefer to store it in
                big-endian and not waste any CPU cycles to convert it to little endian
                (speed is key in this application). The implicit and explicit operators
                are overridden to query header information from the data received. The
                data is then forwarded over many other socket connections in big-endian
                format; thus no byte-swapping conversions are required for the majority of
                the received data.
                >
                Is there no way in C# to map a struct directly on top of a block of
                memory?
                >
                >
                >
                John J. Hughes II wrote:
                >Your assuming the data is sequentially stored and no other data exist in
                >the class, both assumptions are incorrect.
                >>
                >Normally you can serialize your class and desterilized but if the data
                >needs to be in a compact byte array which I have found need for several
                >times you will need to parse the data manually. I think you can overload
                >the serialization function but I have found the below simpler.
                >>
                >class TestA {
                > public ushort val1;
                > public ushort val2;
                > public ushort val3;
                >>
                > public TestA(byte[] data)
                > {
                > val1 = BitConverter.To UInt16(0);
                > val2 = BitConverter.To UInt16(2);
                > val3 = BitConverter.To UInt16(4);
                > }
                > public ToArray
                > {
                > get {
                > MemoryStream ms = new MemoryStream();
                > ms.Wirte(BitCon verter.GetBytes (val1, 0, 2);
                > ms.Wirte(BitCon verter.GetBytes (val2, 0, 2);
                > ms.Wirte(BitCon verter.GetBytes (val3, 0, 2);
                > ms.Capacity = ms.Length;
                > return ms.ToArray();
                > }
                > }
                >}
                >>
                >Regards,
                >John
                >>
                >"O.B." <funkjunk@bells outh.netwrote in message
                >news:12jq3gr59 8l2u1b@corp.sup ernews.com...
                >>I'm trying to do a static_cast at runtime in C# and as I understand it,
                >>"as" is the keyword to use. Unfortunately, the compiler is trying to do
                >>the cast a compilation time. See below.
                >>>
                >>/* TestA.cs */
                >>namespace TEST {
                >> class TestA {
                >> public ushort val1;
                >> public ushort val2;
                >> public ushort val3;
                >> }
                >>}
                >>>
                >>/* Main Program */
                >>namespace TEST {
                >> class Program {
                >> static void Main(string[] args) {
                >> TestA test = null;
                >> byte[] testArray = new byte[6];
                >> for (int i = 0; i < testArray.Lengt h; i++) {
                >> testArray[i] = (byte)(i + 1);
                >> }
                >> // Trying to do a C++-style static_cast
                >> // Compilation error:
                >> // Cannot convert type 'byte[]' to 'TEST.TestA'
                >> // via a built-in conversion
                >> test = testArray as TestA;
                >> }
                >> }
                >>}
                >>>
                >>What am I doing wrong?
                >>

                Comment

                • John J. Hughes II

                  #9
                  Re: Problem casting a byte[] to a class

                  Jon,

                  Most of my solutions (problems) have the wrong Endean so I also have a class
                  for converting. Maybe someday when I have time I will look at yours, you
                  might have some better ways of handling problems.

                  Yes you are correct about the ToArray, when I first write the function I was
                  using the GetBuffer function which was returning the entire capacity. I
                  later switch to the ToArray function and never removed it, thanks for the
                  pointer.

                  Regards,
                  John

                  "Jon Skeet [C# MVP]" <skeet@pobox.co mwrote in message
                  news:MPG.1fa725 c4b27504e698d57 5@msnews.micros oft.com...
                  John J. Hughes II <no@invalid.com wrote:
                  >Your assuming the data is sequentially stored and no other data exist in
                  >the
                  >class, both assumptions are incorrect.
                  >>
                  >Normally you can serialize your class and desterilized but if the data
                  >needs
                  >to be in a compact byte array which I have found need for several times
                  >you
                  >will need to parse the data manually. I think you can overload the
                  >serializatio n function but I have found the below simpler.
                  >
                  Note that for your solution, the line
                  >
                  ms.Capacity = ms.Length;
                  >
                  is unnecessary.
                  >
                  Personally, I'd prefer to create the 6 byte array to start with, and
                  then populate it. The "standard" BitConverter doesn't have any way to
                  convert into the middle of an existing array, but my own one does :)
                  >
                  See http://www.pobox.com/~skeet/csharp/miscutil and the
                  EndianBitConver ter class.
                  >
                  In this case, the code might be (converting it to a method rather than
                  a property);
                  >
                  public byte[] ToArray()
                  {
                  EndianBitConver ter converter = EndianBitConver ter.Little;
                  byte[] ret = new byte[6];
                  converter.CopyB ytes (val1, ret, 0);
                  converter.CopyB ytes (val2, ret, 2);
                  converter.CopyB ytes (val3, ret, 4);
                  return ret;
                  }
                  >
                  --
                  Jon Skeet - <skeet@pobox.co m>
                  http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
                  If replying to the group, please do not mail me too

                  Comment

                  • Tom Spink

                    #10
                    Re: Problem casting a byte[] to a class

                    O.B. wrote:
                    I'm trying to do a static_cast at runtime in C# and as I understand it,
                    "as" is the keyword to use. Unfortunately, the compiler is trying to do
                    the cast a compilation time. See below.
                    >
                    /* TestA.cs */
                    namespace TEST {
                    class TestA {
                    public ushort val1;
                    public ushort val2;
                    public ushort val3;
                    }
                    }
                    >
                    /* Main Program */
                    namespace TEST {
                    class Program {
                    static void Main(string[] args) {
                    TestA test = null;
                    byte[] testArray = new byte[6];
                    for (int i = 0; i < testArray.Lengt h; i++) {
                    testArray[i] = (byte)(i + 1);
                    }
                    // Trying to do a C++-style static_cast
                    // Compilation error:
                    // Cannot convert type 'byte[]' to 'TEST.TestA'
                    // via a built-in conversion
                    test = testArray as TestA;
                    }
                    }
                    }
                    >
                    What am I doing wrong?
                    O.B.,

                    The other guys have explained quite well why you can't do it; and why you
                    shouldn't do it. You've got to remember C# is a managed programming
                    language, it doesn't usually have access to raw memory and the same types
                    of clevery you can do with C++, et al.

                    However, this is how you do it:

                    Firstly, define your TestA as a struct, and give it the attribute of
                    LayoutKind.Sequ ential:

                    ///
                    [StructLayout(La youtKind.Sequen tial)]
                    public struct TestA
                    {
                    public ushort val1;
                    public ushort val2;
                    public ushort val3;
                    }
                    ///

                    Then your new test method should read:

                    ///
                    static void Main( string[] args )
                    {
                    TestA test;

                    byte[] testArray = new byte[6];
                    for ( int i = 0; i < testArray.Lengt h; i++ )
                    testArray[i] = (byte)(i + 1);

                    IntPtr arrayPtr = Marshal.UnsafeA ddrOfPinnedArra yElement( testArray, 0 );
                    test = (TestA) Marshal.PtrToSt ructure( p, typeof( TestA ) );
                    }
                    ///

                    So, the start of the code is the same (loading your array), then the next
                    two lines perform the magic. The first gets a pointer to the start of the
                    byte array, and stores it in arrayPtr. The second then generates the
                    structure, given that pointer and the type of structure being generated.

                    --
                    Hope this helps,
                    Tom Spink

                    Google first, ask later.

                    Comment

                    • Tom Spink

                      #11
                      Re: Problem casting a byte[] to a class

                      Tom Spink wrote:
                      O.B. wrote:
                      >
                      >I'm trying to do a static_cast at runtime in C# and as I understand it,
                      >"as" is the keyword to use. Unfortunately, the compiler is trying to do
                      >the cast a compilation time. See below.
                      >>
                      >/* TestA.cs */
                      >namespace TEST {
                      > class TestA {
                      > public ushort val1;
                      > public ushort val2;
                      > public ushort val3;
                      > }
                      >}
                      >>
                      >/* Main Program */
                      >namespace TEST {
                      > class Program {
                      > static void Main(string[] args) {
                      > TestA test = null;
                      > byte[] testArray = new byte[6];
                      > for (int i = 0; i < testArray.Lengt h; i++) {
                      > testArray[i] = (byte)(i + 1);
                      > }
                      > // Trying to do a C++-style static_cast
                      > // Compilation error:
                      > // Cannot convert type 'byte[]' to 'TEST.TestA'
                      > // via a built-in conversion
                      > test = testArray as TestA;
                      > }
                      > }
                      >}
                      >>
                      >What am I doing wrong?
                      >
                      O.B.,
                      >
                      The other guys have explained quite well why you can't do it; and why you
                      shouldn't do it. You've got to remember C# is a managed programming
                      language, it doesn't usually have access to raw memory and the same types
                      of clevery you can do with C++, et al.
                      >
                      However, this is how you do it:
                      >
                      Firstly, define your TestA as a struct, and give it the attribute of
                      LayoutKind.Sequ ential:
                      >
                      ///
                      [StructLayout(La youtKind.Sequen tial)]
                      public struct TestA
                      {
                      public ushort val1;
                      public ushort val2;
                      public ushort val3;
                      }
                      ///
                      >
                      Then your new test method should read:
                      >
                      ///
                      static void Main( string[] args )
                      {
                      TestA test;
                      >
                      byte[] testArray = new byte[6];
                      for ( int i = 0; i < testArray.Lengt h; i++ )
                      testArray[i] = (byte)(i + 1);
                      >
                      IntPtr arrayPtr = Marshal.UnsafeA ddrOfPinnedArra yElement( testArray, 0
                      ); test = (TestA) Marshal.PtrToSt ructure( p, typeof( TestA ) );
                      }
                      ///
                      >
                      So, the start of the code is the same (loading your array), then the next
                      two lines perform the magic. The first gets a pointer to the start of the
                      byte array, and stores it in arrayPtr. The second then generates the
                      structure, given that pointer and the type of structure being generated.
                      >
                      I made a slight error while I was touch-typing from monitor 1, to monitor 2:

                      On the line of code that is PtrToStructure, I left the first parameter as p,
                      when in fact it should be arrayPtr. Appologies.

                      --
                      Hope this helps,
                      Tom Spink

                      Google first, ask later.

                      Comment

                      • John J. Hughes II

                        #12
                        Re: Problem casting a byte[] to a class

                        I don't understand why you are coping the data from one array to another,
                        just use the array the UdpClient is giving you.

                        Personally I normally use socket and have found the socket can not give you
                        data as fast as you can process it so you will be spending more time idle
                        anyway so you might be trying to optimize something more then needed.

                        Regards,
                        John

                        "O.B." <funkjunk@bells outh.netwrote in message
                        news:12jq73lfmv orc9b@corp.supe rnews.com...
                        This is *real* close to what I want. The only drawback is that I'm having
                        to instantiate new memory for the TestA structure before calling Marshal.
                        The UdpClient is already returning an allocated byte array. This
                        application has to run as close to real-time as possible.
                        >
                        TestA test;
                        byte[] testArray = new byte[6];
                        for (int i = 0; i < testArray.Lengt h; i++) {
                        testArray[i] = (byte)(i + 1);
                        }
                        Marshal.Copy(te stArray, 0, (IntPtr)(&test) , 6);
                        >
                        >
                        >
                        John J. Hughes II wrote:
                        >Oh by the way if you convert to a structure and set the offsets manually
                        >you can then do a memory copy to accomplish what you did in C.
                        >>
                        >Sort of like this, don't do it as often so a little fuzzer on how.
                        >>
                        >[StructLayout(La youtKind.Explic it)]
                        >public struct TestA
                        >{
                        > [FieldOffset(0)] public ushort Val1;
                        > [FieldOffset(2)] public ushort Val2;
                        > [FieldOffset(4)] public ushort Val2;
                        >}
                        >>
                        >Marshal.Copy(D ata, 0, IntPtr <TestA>, 6);
                        >>
                        >Regards,
                        >John
                        >>
                        >"O.B." <funkjunk@bells outh.netwrote in message
                        >news:12jq3gr59 8l2u1b@corp.sup ernews.com...
                        >>I'm trying to do a static_cast at runtime in C# and as I understand it,
                        >>"as" is the keyword to use. Unfortunately, the compiler is trying to do
                        >>the cast a compilation time. See below.
                        >>>
                        >>/* TestA.cs */
                        >>namespace TEST {
                        >> class TestA {
                        >> public ushort val1;
                        >> public ushort val2;
                        >> public ushort val3;
                        >> }
                        >>}
                        >>>
                        >>/* Main Program */
                        >>namespace TEST {
                        >> class Program {
                        >> static void Main(string[] args) {
                        >> TestA test = null;
                        >> byte[] testArray = new byte[6];
                        >> for (int i = 0; i < testArray.Lengt h; i++) {
                        >> testArray[i] = (byte)(i + 1);
                        >> }
                        >> // Trying to do a C++-style static_cast
                        >> // Compilation error:
                        >> // Cannot convert type 'byte[]' to 'TEST.TestA'
                        >> // via a built-in conversion
                        >> test = testArray as TestA;
                        >> }
                        >> }
                        >>}
                        >>>
                        >>What am I doing wrong?
                        >>

                        Comment

                        • Ben Voigt

                          #13
                          Re: Problem casting a byte[] to a class


                          "O.B." <funkjunk@bells outh.netwrote in message
                          news:12jq73lfmv orc9b@corp.supe rnews.com...
                          This is *real* close to what I want. The only drawback is that I'm having
                          to instantiate new memory for the TestA structure before calling Marshal.
                          The UdpClient is already returning an allocated byte array. This
                          application has to run as close to real-time as possible.
                          This whole business breaks all type-safety rules (only the BitConverter
                          method was type-safe).

                          If that's ok with you, and it sounds like it is, then use explicit layout
                          and pointers inside an unsafe block.

                          >
                          TestA test;
                          byte[] testArray = new byte[6];
                          for (int i = 0; i < testArray.Lengt h; i++) {
                          testArray[i] = (byte)(i + 1);
                          }
                          Marshal.Copy(te stArray, 0, (IntPtr)(&test) , 6);
                          >
                          >
                          >
                          John J. Hughes II wrote:
                          >Oh by the way if you convert to a structure and set the offsets manually
                          >you can then do a memory copy to accomplish what you did in C.
                          >>
                          >Sort of like this, don't do it as often so a little fuzzer on how.
                          >>
                          >[StructLayout(La youtKind.Explic it)]
                          >public struct TestA
                          >{
                          > [FieldOffset(0)] public ushort Val1;
                          > [FieldOffset(2)] public ushort Val2;
                          > [FieldOffset(4)] public ushort Val2;
                          >}
                          >>
                          >Marshal.Copy(D ata, 0, IntPtr <TestA>, 6);
                          >>
                          >Regards,
                          >John
                          >>
                          >"O.B." <funkjunk@bells outh.netwrote in message
                          >news:12jq3gr59 8l2u1b@corp.sup ernews.com...
                          >>I'm trying to do a static_cast at runtime in C# and as I understand it,
                          >>"as" is the keyword to use. Unfortunately, the compiler is trying to do
                          >>the cast a compilation time. See below.
                          >>>
                          >>/* TestA.cs */
                          >>namespace TEST {
                          >> class TestA {
                          >> public ushort val1;
                          >> public ushort val2;
                          >> public ushort val3;
                          >> }
                          >>}
                          >>>
                          >>/* Main Program */
                          >>namespace TEST {
                          >> class Program {
                          >> static void Main(string[] args) {
                          >> TestA test = null;
                          >> byte[] testArray = new byte[6];
                          >> for (int i = 0; i < testArray.Lengt h; i++) {
                          >> testArray[i] = (byte)(i + 1);
                          >> }
                          >> // Trying to do a C++-style static_cast
                          >> // Compilation error:
                          >> // Cannot convert type 'byte[]' to 'TEST.TestA'
                          >> // via a built-in conversion
                          >> test = testArray as TestA;
                          >> }
                          >> }
                          >>}
                          >>>
                          >>What am I doing wrong?
                          >>

                          Comment

                          Working...