Marshal NOT 0 terminated string

2019-05-11 19:25发布

问题:

I have the folowing unmanaged structure.

struct MyNativeStruct_Foo
{   
 char product_name[4];
 char product_model[2];
}

And the managed equivalent

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct MyManagedStruct_Foo
{
    [MarshalAs(UnmanagedType.LPStr, SizeConst = 4)]
    public string product_name;

    [MarshalAs(UnmanagedType.LPStr, SizeConst = 2)]
    public string product_model;
}

Unfortunately the stings are not null terminated. All 4 characters for the product name are used. If I define the managed structure with "LPStr" the string have to be 0 terminated.

Is there another way to define the managed structure? It is possible to define a custom Marshaller attribute? Or do you have other Ideas?

Note; The native structure can not be changed.

Thanks

Amberg

[EDIT] changed to LPStr (comment Jason Larke)

回答1:

You can change your marshalling to treat the string as a fixed-size array of bytess and then using the Encoding class to convert the bytes into a managed string.

i.e

[StructLayout(LayoutKind.Sequential)]
public struct MyManagedStruct_Foo
{
    [MarshalAs(UnmanagedType.ByValArray, SizeConst=4)]
    public byte[] product_name;

    [MarshalAs(UnmanagedType.ByValArray, SizeConst=2)]
    public byte[] product_model;

    public string GetProductName()
    {
        return System.Text.Encoding.ASCII.GetString(this.product_name);
    }

    public string GetProductModel()
    {
        return System.Text.Encoding.ASCII.GetString(this.product_model);
    }
}

Not exactly the sexiest struct in the world, but it should be fine for your needs.