Make only one method of array of any kind to IntPtr
c#
Solution
The best approach would be to make an extension class that did this for you, for each type. You cannot make it generic as `Marshal.Copy()` does not support a generic type. So you will have to duplicate your method for each type `byte`, `char`, `int`, `long`, `float`, `double`, etc. However, you can make a generic helper method for determining your size to `Marshsal`.
Something like below could be useful to you:
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);
}
}
The main benefit is in your code you could easily do something like:
var myArray = { 0, 1, 2, 3, 4, 5, ... }
var ptr = myArray.CopyToCoTaskMem();
NOTE: Just be sure to call `Marshal.FreeCoTaskMem()` when you are done with it! I would recommend your extension method returning an `IDisposable` object so you can wrap it in a `using` block.
For example:
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;
}
}
Then your modified extension class method:
public static CoTaskMemoryHandle CopyToCoTaskMem(this byte[] array)
{
var ptr = AllocArrayCoTaskMem(array);
Marshal.Copy(array, 0, ptr, array.Length);
return new CoTaskMemoryHandle(ptr);
}
This way you can safely encapsulate the `Alloc`/`Free` balancing:
using(myArray.CopyToCoTaskMem())
{
// Do something here..
}
Problem
Having a method to convert `double[] d` to `IntPtr` like: ``` public static IntPtr DoubleArrayToIntPtr(double[] d) { IntPtr p = Marshal.AllocCoTaskMem(sizeof(double) * d.Length); Marshal.Copy(d, 0, p, d.Length); return p; } ``` What would be the best way to make `int[]`, `float[]`, etc. I was thinking on making one method for each type like adding int[]: ``` public static IntPtr IntArrayToIntPtr(int[] d) { IntPtr p = Marshal.AllocCoTaskMem(sizeof(int) * d.Length); Marshal.Copy(d, 0, p, d.Length); return p; } ``` 1. Could this method be generalized, if so how? 2. Is it possible to get pointer in only one line of code (As Marshal is void method)?