0

Is there any Marshal method which instantiate a formatted ready-to-use object?

By "formatted" I mean a struct that have its layout formatted with attributes like StructLayout and MarshalAs.

Some code to clarification bellow.

public struct s1
{
    public int i1;
    public int i2;
}

public struct s2
{
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
    public s1[] _s1;
}

What I want is to call some Marshal method that will actually return a ready-to-use formatted instance of s2. Some code again to help the understanding.

    s2 temp = Marshal<s2>.CrateEmpty();
    int i = temp._s1[2].i1;

I need this functionality to avoid creating in each of my structs a method to make this formatting stuff. In the code above, Marshal.CreateEmpty() should be able to instantiate s2._s1 as an array with 5 elements.

Any thoughts?

Thanks.

andresantacruz
  • 1,676
  • 10
  • 17
  • 1
    Your `SizeConst` is wrong, if the array have 5 elements then you want 5*8 aka `SizeConst = 0x28`. Your s1 structure size is of 8 bytes. – Prix Apr 14 '16 at 10:38
  • No @Prix, it's not. The definition of MarshalAs.SizeConst is the following: "Indicates the number of elements in the fixed-length array or the number of characters (not bytes) in a string to import.". – andresantacruz Apr 14 '16 at 10:40
  • 1
    Fairly difficult to understand what this question is about. The most "ready to use" version is certainly `new s2()`. Conversion from the managed to the native layout normally happens at the last possible moment, a standard duty of the pinvoke marshaller. Otherwise also exposed as Marshal.StructureToPtr(). – Hans Passant Apr 14 '16 at 12:53
  • @HansPassant Imagine I have a byte[] representing the data sent through a tcp connection, I want to have some high-level representation of that packet in my code. So the idea is to use Marshal.PtrToStructure to "convert" the byte[] to my custom structs. – andresantacruz Apr 14 '16 at 12:58
  • I wouldn't have any problems with this if C# could allow fixed-size array of custom types, this is the root of all the problems I'm facing atm :( – andresantacruz Apr 14 '16 at 13:02
  • 1
    Well, make it so. You need to call GCHandle.Alloc + GCHandle.AddrOfPinnedObject to get the Ptr you need. Nothing "ready to use", [write a generic method](http://stackoverflow.com/a/1936208/17034) so it works for any structure type T. Using XML or something like Protobuf if it has to be binary is generally the more productive way to go about it. – Hans Passant Apr 14 '16 at 13:09
  • @HansPassant Your solution solves the problem of marshaling a byte[] to a structure, but what about marshaling a structure to a byte[]? Before being ready to call Marshal.StructureToPtr I have to initialize the array in s2, dont I? – andresantacruz Apr 14 '16 at 13:27
  • Just edited my comment above. – andresantacruz Apr 14 '16 at 13:29

0 Answers0