最好的辦法是做一個擴展類,爲你做,爲每種類型。由於Marshal.Copy()
不支持泛型,因此不能使其通用。所以,你必須重複你的方法對每種類型byte
,char
,int
,long
,float
,double
等。但是,你可以爲你的決定大小Marshsal
一個通用的helper方法。
類似下面可能對你有用:
public static class MarshalExtender
{
public static IntPtr CopyToCoTaskMem(this byte[] array)
{
var ptr = AllocArrayCoTaskMem(array);
Marshal.Copy(array, 0, ptr, array.Length);
return ptr;
}
// Copy the above method and replace types as needed (int, double, etc).
// Helper method for allocating bytes with generic arrays.
static IntPtr AllocArrayCoTaskMem<T>(T[] array)
{
var type = typeof(T);
var size = Marshal.SizeOf(type) * array.Length;
return Marshal.AllocCoTaskMem(size);
}
}
主要的好處是在你的代碼,你可以很容易地做一些事情,如:
var myArray = { 0, 1, 2, 3, 4, 5, ... }
var ptr = myArray.CopyToCoTaskMem();
注:只是一定要打電話Marshal.FreeCoTaskMem()
當你完成它!我建議你的擴展方法返回一個IDisposable
對象,這樣你可以將它包裝在using
塊中。
例如:
public sealed class CoTaskMemoryHandle : IDisposable
{
bool isDisposed;
readonly IntPtr handle;
public IntPtr Handle { get { return handle; } }
public CoTaskMemoryHandle(IntPtr handle)
{
this.handle = handle;
}
public void Dispose()
{
OnDispose(true);
GC.SuppressFinalize(this);
}
void OnDispose(bool isDisposing)
{
if (isDisposed) return;
if (isDisposing)
{
if (handle != IntPtr.Zero)
Marshal.FreeCoTaskMem(handle);
}
isDisposed = true;
}
}
然後修改後的擴展類方法:
public static CoTaskMemoryHandle CopyToCoTaskMem(this byte[] array)
{
var ptr = AllocArrayCoTaskMem(array);
Marshal.Copy(array, 0, ptr, array.Length);
return new CoTaskMemoryHandle(ptr);
}
這樣,您就可以放心地封裝Alloc
/Free
平衡:
using(myArray.CopyToCoTaskMem())
{
// Do something here..
}
你需要什麼intptr爲 - 確定如何編組。 –
你真的想要一個副本,或者只是[指向固定數組的指針](http://stackoverflow.com/a/4097057/11683)? – GSerg
文字轉換模板工具包。簡稱T4。 – Theraot