25 Ocak 2018 Perşembe

Marshal Sınıfı

AllocHGlobal metodu
Elimizde şöyle bir kod olsun.
[StructLayout(LayoutKind.Sequential)]
public struct MyStruct
{
  public ushort a;
  public uint b;
  public uint c;
  public ushort d;
}
Bu struct'ı belleğe yazmak için şöyle yaparız.
int size = Marshal.SizeOf(typeof(T));
byte[] arr = new byte[size];
IntPtr ptr = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(str, ptr, true);
Marshal.Copy(ptr, arr, 0, size);
Marshal.FreeHGlobal(ptr);
Copy metodu
Şöyle yaparız.
byte[] arr = new byte[....];
IntPtr ptr = Marshal.AllocHGlobal(...);
...
Marshal.Copy(ptr, arr, 0, size);
FreeHGlobal metodu
Şöyle yaparız.
IntPtr ptr = Marshal.AllocHGlobal(...);
...
Marshal.FreeHGlobal(ptr);
GetLastWin32Error metodu
Elimizde şöyle bir kod olsun.
[DllImport("Kernel32.dll", SetLastError = true)]
public static extern IntPtr CreateConsoleScreenBuffer(
    uint dwDesiredAccess,
    uint dwShareMode,
    IntPtr secutiryAttributes,
    uint flags,
    IntPtr screenBufferData
);

public const int GENERIC_WRITE = 0x4000000;
public const int FILE_SHARE_WRITE = 2;
public const int CONSOLE_TEXTMODE_BUFFER = 1;
Şöyle yaparız.
IntPtr tempConsole = CreateConsoleScreenBuffer(
    GENERIC_WRITE, 
    FILE_SHARE_WRITE, 
    IntPtr.Zero, 
    CONSOLE_TEXTMODE_BUFFER, 
    IntPtr.Zero
);

int error = Marshal.GetLastWin32Error();
OffsetOf metodu
Şöyle yaparız.
public static class StructSerializer
{
  public static byte[] Serialize<T>(T data) where T : struct
  {
    List<byte> result = new List<byte>();
    Type type = data.GetType();
    IEnumerable<FieldInfo> orderedFields = type.GetFields().OrderBy(f =>
      Marshal.OffsetOf(type, f.Name).ToInt32());

    foreach (FieldInfo fieldInfo in orderedFields)
    {
      object value = fieldInfo.GetValue(data);
      MethodInfo conversion = typeof(BitConverter).GetMethod(
        nameof(BitConverter.GetBytes), new[]{fieldInfo.FieldType});
      if (conversion == null) continue;
      byte[] converted = (byte[])conversion.Invoke(null, new []{value});
      result.AddRange(converted);
    }

    return result.ToArray();
  }
}
SizeOf metodu
Bir tipin büyüklüğünü öğrenmek için şöyle yaparız.
int size = Marshal.SizeOf(typeof(T));
StructureToPtr metodu
Bir struc'ı belleğe yazmak için kullanılır.
Örnek
Elimizde bir struct olsun.
[StructLayout(LayoutKind.Sequential)]
public struct CStruct
{
    //member-list
}
Bunu bir çağrıya geçmek için şöyle yaparız.
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CStruct)));
try{
    Marshal.StructureToPtr(myCStruct, ptr, false);
    DLLFunction(ptr, ...);
} finally {
    Marshal.FreeHGlobal(ptr);
}
Örnek
Eğer ptr daha öncede bir alanı gösteriyorsa şöyle yaparız.
Marshal.StructureToPtr(myStruct, ptr, true);

Hiç yorum yok:

Yorum Gönder