Marshalling a structure to contain an array whose length is an earlier struct member?
-
For loading a file that was originally written by an application written in C++, I have been declaring each part of the file as a struct, and converting the data into a struct using this function:
public static TStruct GetStruct<TStruct>(byte[] data,Type t)
where TStruct : new()
{
int structSize = Marshal.SizeOf(typeof(TStruct));
TStruct outstruct = new TStruct();
GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);
outstruct = (TStruct)Marshal.PtrToStructure(handle.AddrOfPinnedObject(),t);
handle.Free();
return outstruct;
}This works fine for structs that do not contain arrays or that contain only arrays that can be defined using fixed (eg fixed int someVariable[10]; works fine) ,but I run into a problem when I want to do this to a struct such as:
struct Foobar
{
int count;
customStructType someStruct[count];
}I've tried using [MarshalAs(UnmanagedType.<tried all these>, <parameters specified type takes here>)] but it either requires me to specify a fixed number upfront or causes my GetStruct method to give me an error that it "could not meaningfully obtain the size of the struct". LPArray allowed me to specify a particular element in the struct that acts as the number of elements in the array but that gave me the aforementioned lack of meaningful size error. Is there any way to make this work?
-
For loading a file that was originally written by an application written in C++, I have been declaring each part of the file as a struct, and converting the data into a struct using this function:
public static TStruct GetStruct<TStruct>(byte[] data,Type t)
where TStruct : new()
{
int structSize = Marshal.SizeOf(typeof(TStruct));
TStruct outstruct = new TStruct();
GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);
outstruct = (TStruct)Marshal.PtrToStructure(handle.AddrOfPinnedObject(),t);
handle.Free();
return outstruct;
}This works fine for structs that do not contain arrays or that contain only arrays that can be defined using fixed (eg fixed int someVariable[10]; works fine) ,but I run into a problem when I want to do this to a struct such as:
struct Foobar
{
int count;
customStructType someStruct[count];
}I've tried using [MarshalAs(UnmanagedType.<tried all these>, <parameters specified type takes here>)] but it either requires me to specify a fixed number upfront or causes my GetStruct method to give me an error that it "could not meaningfully obtain the size of the struct". LPArray allowed me to specify a particular element in the struct that acts as the number of elements in the array but that gave me the aforementioned lack of meaningful size error. Is there any way to make this work?
Nasty one. AFAIK .NET does not allow any direct coding that will create a structure whose length is not fixed at compile time - and I can understand why not. I haven't tried it, but this[^] appears to address the problem. In a suitably nasty way, of course... :laugh:
Real men don't use instructions. They are only the manufacturers opinion on how to put the thing together.