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?
char[]
to string
.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).[MarshalAs]
attribute is ignored unless you are passing the instance to unmanaged code, and there is no indication that you are doing so.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 theSystem.Runtime.InteropServices.CharSet
argument of theSystem.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)]