I'm trying to abstract marshaling IntPtr to and from structs (actually class, so it's reference type) of data shared with native code.
I have this helper class:
class NativeStruct<StructType> : IDisposable
{
public NativeStruct()
{
_DataPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(StructType)));
Marshal.PtrToStructure(_DataPtr, _Data);
}
public NativeStruct(IntPtr dataPtr)
{
_DataPtr = dataPtr;
Marshal.PtrToStructure(_DataPtr, _Data);
}
void IDisposable.Dispose()
{
Marshal.StructureToPtr(_Data, _DataPtr, true);
}
public StructType Data { get { return _Data; } }
IntPtr _DataPtr;
public StructType _Data;
}
Is there anyway to make this code implicit:
using (Shared_s data = new Toolbox.NativeStruct<DataStruct>(myIntPtr).Data)
{
data.someMember = someValue;
}
Some way to change this to
EditStruct(DataStruct, myIntPtr)
{
data.someMember = someValue;
}
In C++ I would have used a macro like
#define EditStruct(StructType, IntPtr) using \
(Shared_s data = new Toolbox.NativeStruct<StructType>(IntPtr).data)
The closest thing you can do here is use lambda expressions:
EditStruct<DataStruct>(myIntPtr, data =>
{
data.someMember = someValue;
});
Definition of EditStruct()
:
void EditStruct<TStruct>(IntPtr dataPtr, Action<TStruct> action)
where TStruct : struct
{
using (var s = new Toolbox.NativeStruct<TStruct>(dataPtr))
{
action(s.Data);
}
}