Reputation: 41
I'm using native functions and have small problem with marshaling structs in c#. I have pointer to struct in another struct - e.g. C# declarations:
[StructLayout(LayoutKind.Sequential, Pack=1, CharSet = CharSet.Auto)]
public struct PARENT
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string Name;
[MarshalAs(UnmanagedType.Struct, SizeConst=8)]
public CHILD pChild;
}
[StructLayout(LayoutKind.Sequential, Pack=1, CharSet = CharSet.Auto)]
public struct CHILD
{
public UInt32 val1;
public UInt32 val2;
}
In PARENT struct I should have a pointer to CHILD struct. I need to pass a 'pointer to reference' (of PARENT struct) as argument of API function.
There's no problem with single reference ("ref PARENT" as argument of imported dll function) but how to pass "ref ref" ? Is it possible without using unsafe code (with C pointer) ?
greetings Arthur
Upvotes: 4
Views: 3541
Reputation: 7411
If you do not want to use unsafe code, then you need to define Child as IntPtr and add a property which access then the values from the Child IntPtr.
[StructLayout(LayoutKind.Sequential, Pack=1, CharSet = CharSet.Auto)]
public struct PARENT
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string Name;
public IntPtr pChild;
public CHILD Child{
get {
return (CHILD)Marshal.PtrToStructure(pChild, typeof(CHILD));
}
}
}
[StructLayout(LayoutKind.Sequential, Pack=1, CharSet = CharSet.Auto)]
public struct CHILD
{
public UInt32 val1;
public UInt32 val2;
}
I think it is easier and cleaner with unsafe code/pointers.
Upvotes: 1
Reputation: 14532
This is a combination of safe and unsafe, as I believe is reasonable here.
fixed (void* pt = new byte[Marshal.SizeOf(myStructInstance)])
{
var intPtr = new IntPtr(pt);
Marshal.StructureToPtr(myStructInstance, intPtr, true);
// now "pt" is a pointer to your struct instance
// and "intPtr" is the same, but wrapped with managed code
}
Upvotes: 0