Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Compile error: Using strings inside Struct with LayoutKind.Explicit

Compile error: Using strings inside Struct with LayoutKind.Explicit

Scheduled Pinned Locked Moved C#
helplounge
4 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • U Offline
    U Offline
    User 3491102
    wrote on last edited by
    #1

    Getting compile (Overwritten area/contains Object field @ offset 21) I want a string that is of length 11 (sender) and a string that is of length 23 (message). Any help is appreciated; I cant see the problem. [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 66, CharSet = CharSet.Ansi)] public struct chat { [FieldOffset(0)] public int packetType; //4 [FieldOffset(4)] public int packetNumber; //4 [FieldOffset(8)] public int packetSource; //4 [FieldOffset(12)] public int packetDestination; //4 [FieldOffset(16)] public short packetPort; // 2 [FieldOffset(18)] public ushort packetInfoEnd; // 2 [FieldOffset(20)] public byte dataId; // 1 [FieldOffset(21)] public string dataSender; // 11 [FieldOffset(32)] public byte dataPadOne; // 1 [FieldOffset(33)] public string dataMessage; // 23 [FieldOffset(56)] public short dataPart; // 2 [FieldOffset(58)] public int dataEndCodeOne; // 4 [FieldOffset(62)] public int dataEndCodeTwo; // 4 public chat(int dst, short port, string sender, string message) { packetType = 1192961; packetNumber = 0; packetSource = 0; packetDestination = dst; packetPort = IPAddress.HostToNetworkOrder(port); packetInfoEnd = 43521; dataId = 10; dataSender = sender; dataPadOne = 0; dataMessage = message; dataPart = 206; dataEndCodeOne = 10209786; dataEndCodeTwo = 6658; } }

    L 1 Reply Last reply
    0
    • U User 3491102

      Getting compile (Overwritten area/contains Object field @ offset 21) I want a string that is of length 11 (sender) and a string that is of length 23 (message). Any help is appreciated; I cant see the problem. [StructLayout(LayoutKind.Explicit, Pack = 1, Size = 66, CharSet = CharSet.Ansi)] public struct chat { [FieldOffset(0)] public int packetType; //4 [FieldOffset(4)] public int packetNumber; //4 [FieldOffset(8)] public int packetSource; //4 [FieldOffset(12)] public int packetDestination; //4 [FieldOffset(16)] public short packetPort; // 2 [FieldOffset(18)] public ushort packetInfoEnd; // 2 [FieldOffset(20)] public byte dataId; // 1 [FieldOffset(21)] public string dataSender; // 11 [FieldOffset(32)] public byte dataPadOne; // 1 [FieldOffset(33)] public string dataMessage; // 23 [FieldOffset(56)] public short dataPart; // 2 [FieldOffset(58)] public int dataEndCodeOne; // 4 [FieldOffset(62)] public int dataEndCodeTwo; // 4 public chat(int dst, short port, string sender, string message) { packetType = 1192961; packetNumber = 0; packetSource = 0; packetDestination = dst; packetPort = IPAddress.HostToNetworkOrder(port); packetInfoEnd = 43521; dataId = 10; dataSender = sender; dataPadOne = 0; dataMessage = message; dataPart = 206; dataEndCodeOne = 10209786; dataEndCodeTwo = 6658; } }

      L Offline
      L Offline
      Luc Pattyn
      wrote on last edited by
      #2

      Hi, in .NET a string is a reference type, so a struct (or anything else) containing a string is actually containing a reference (similar to a pointer), which must and will be "naturally aligned", that is at an offset which is a multiple of 4 or 8. If you must have the content of an array or even a string embedded inside the struct, you can try this:

      [MarshalAs(UnmanagedType.ByValTStr,SizeConst=32)]
      public string dmDeviceName;
      [MarshalAs(UnmanagedType.ByValArray, SizeConst=15)]
      public int[] data;

      that effectively turns reference types into value types as far as storage allocation goes. :)

      Luc Pattyn [Forum Guidelines] [My Articles]


      - before you ask a question here, search CodeProject, then Google - the quality and detail of your question reflects on the effectiveness of the help you are likely to get - use the code block button (PRE tags) to preserve formatting when showing multi-line code snippets


      modified on Sunday, June 12, 2011 8:29 AM

      U 2 Replies Last reply
      0
      • L Luc Pattyn

        Hi, in .NET a string is a reference type, so a struct (or anything else) containing a string is actually containing a reference (similar to a pointer), which must and will be "naturally aligned", that is at an offset which is a multiple of 4 or 8. If you must have the content of an array or even a string embedded inside the struct, you can try this:

        [MarshalAs(UnmanagedType.ByValTStr,SizeConst=32)]
        public string dmDeviceName;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst=15)]
        public int[] data;

        that effectively turns reference types into value types as far as storage allocation goes. :)

        Luc Pattyn [Forum Guidelines] [My Articles]


        - before you ask a question here, search CodeProject, then Google - the quality and detail of your question reflects on the effectiveness of the help you are likely to get - use the code block button (PRE tags) to preserve formatting when showing multi-line code snippets


        modified on Sunday, June 12, 2011 8:29 AM

        U Offline
        U Offline
        User 3491102
        wrote on last edited by
        #3

        Thank you! It worked perfectly! Very much appreciated

        1 Reply Last reply
        0
        • L Luc Pattyn

          Hi, in .NET a string is a reference type, so a struct (or anything else) containing a string is actually containing a reference (similar to a pointer), which must and will be "naturally aligned", that is at an offset which is a multiple of 4 or 8. If you must have the content of an array or even a string embedded inside the struct, you can try this:

          [MarshalAs(UnmanagedType.ByValTStr,SizeConst=32)]
          public string dmDeviceName;
          [MarshalAs(UnmanagedType.ByValArray, SizeConst=15)]
          public int[] data;

          that effectively turns reference types into value types as far as storage allocation goes. :)

          Luc Pattyn [Forum Guidelines] [My Articles]


          - before you ask a question here, search CodeProject, then Google - the quality and detail of your question reflects on the effectiveness of the help you are likely to get - use the code block button (PRE tags) to preserve formatting when showing multi-line code snippets


          modified on Sunday, June 12, 2011 8:29 AM

          U Offline
          U Offline
          User 3491102
          wrote on last edited by
          #4

          Just a note for anyone else who comes across this issue and sees this thread: The solution provided by Luc does NOT WORK with LayoutKind.Explicit, it only works with LayoutKind.Sequential, and with the FieldOffset()'s removed (obviously). This is the compiling + working code:

          [StructLayout(LayoutKind.Sequential, Pack = 1, Size = 66, CharSet = CharSet.Ansi)]
          public struct chatOne
          {

                          public int packetType; //4
                          public int packetNumber; //4
                          public int packetSource; //4
                          public int packetDestination; //4
                          public short packetPort; // 2
                          public ushort packetInfoEnd; // 2
                          public byte dataId; // 1
                          \[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 11)\]
                          public string dataSender; // 11
                          public byte dataPadOne; // 1
                          \[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 23)\]
                          public string dataMessage; // 23
                          public short dataPart; // 2
                          public int dataEndCodeOne; // 4
                          public int dataEndCodeTwo; // 4
          
                          public chatOne(int dst, short port, string sender, string message)
                          {
                              packetType = 1192961;
                              packetNumber = 0;
                              packetSource = 0;
                              packetDestination = dst;
                              packetPort = IPAddress.HostToNetworkOrder(port);
                              packetInfoEnd = 43521;                      
                              dataId = 10;
                              dataSender = sender;
                              dataPadOne = 0;
                              dataMessage = message;
                              dataPart = 206;
                              dataEndCodeOne = 10209786;
                              dataEndCodeTwo = 6658;
                          }
                      }
          
          1 Reply Last reply
          0
          Reply
          • Reply as topic
          Log in to reply
          • Oldest to Newest
          • Newest to Oldest
          • Most Votes


          • Login

          • Don't have an account? Register

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • World
          • Users
          • Groups