Question

I was doing something like this:

    [StructLayout(LayoutKind.Sequential)]
     public struct V_REQUEST
     {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024)]
        private string payLoad;

                public string payLoadStr
                {
                    set
                    {
                        if (value != null)                                                               
                            payLoad = value.PadRight(value.Length+1, '\0').ToCharArray();
                    }
                }

     }  
   public object somemethod(byte[] bytes_data)
   {
      string strrequest = Encoding.GetString(bytes_data);

      myobj.payLoad = strrequest;
   }

and this would always mess up my data. I mean I will see some weird characters in my data.

Then I replaced my property with this:

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1024)]
private byte[] payLoad;

            public string payLoadStr
            {
                set
                {
                    if (value != null)   
                    {                                    
                      for (int i = 0; i < value.Length; i++)
                        payLoad[i] = value[i];
                    }
                }
             }

and it works beautifully!!! Why is ToCharArray unsafe?

Was it helpful?

Solution

  1. Your first example doesn't compile. You can't assign char[] to string.
  2. The call to PadRight in the first example does nothing, because you passed value.Length as the argument (obviously no padding is needed to make a string as long as it already is).
  3. The [MarshalAs] attribute is ignored unless you are passing the instance to unmanaged code, and there is no indication that you are doing so.
  4. The UnmanagedType enumeration does not have a member ByValStr. It does have a member ByValTStr.

My guess is you did not specify the correct character set, and the unmanaged code is expecting a single-byte encoding but receiving a 2-byte UTF-16 encoded string. According to the documentation of ByValTStr:

Used for in-line, fixed-length character arrays that appear within a structure. The character type used with ByValTStr is determined by the System.Runtime.InteropServices.CharSet argument of the System.Runtime.InteropServices.StructLayoutAttribute applied to the containing structure.

So you probably forgot to add the following to the containing structure:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]

OTHER TIPS

Does mono have an implicit cast from char[] to string ?

Just wondering why payLoad is a string in the first example and a char[] in the second

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top