如何获取指向数组实例内存的指针



网络上有很多关于如何获取指向byte[]int[,]的指针的例子,即当您确切地知道数组的元素类型和秩时。但是如何获得通用Array的指针呢?

这里的主要问题是我不知道排名靠前。我也不知道元素类型,但我知道(在我的情况下(只能有基元数字类型,所以我可以键入一些额外的if来处理它。

背景:我想制定这个解决方案https://stackoverflow.com/a/52750659/6734314更通用——在其当前形式中,它仅适用于double[,],因此给出了经典的rank+类型:

double[,] doubles =  {
{ 1, 2, 3, 4 },
...
};
fixed (double* p = doubles)
{
...

第一次尝试

从奥利维尔的回答来看,所有的错误都是我的。

Array data = new float[,] { { 4, 2 }, { 77, 3 } };
var reference = __makeref(data);
IntPtr pointer = **(IntPtr**)(&reference);
float* ptr = (float*)pointer.ToPointer();
{
for (int i = 0; i < data.LongLength; ++i)
Console.WriteLine(ptr[i]);
}

组合:

C#中对象的内存地址

如何在C#中显示指针地址?

写作:

Array array = Array.CreateInstance(typeof(int), 10);
unsafe
{
var reference = __makeref(array);
var pointer = **(IntPtr**)( &reference );
Console.WriteLine("0x{0:x}", (ulong)&reference);
Console.WriteLine("0x{0:x}", (long)&reference);
Console.WriteLine("0x{0:x}", (ulong)pointer);
Console.WriteLine("0x{0:x}", (long)pointer);
}

输出:

0x8cb87af070
0x8cb87af070
0x1a9c1c46290
0x1a9c1c46290

Array类的源代码

如果数据始终是相同的形状(例如,2D矩形阵列(,但可能是不同的类型,则可以使用T : unmanaged约束和fixed关键字:

static void Main()
{
// sample taken from comtrade91.pdf section 6.6
var data = new float[,] { { 4, 2 }, { 77, 3 } };
ShowAddressAndData(data);
}
static unsafe void ShowAddressAndData<T>(T[,] data) where T : unmanaged
{
fixed(T* ptr = data)
{
Console.WriteLine((IntPtr)ptr);
for (int i = 0; i < data.Length; i++)
{
Console.WriteLine(ptr[i]);
}
}
}
// this extra method just to show that we can overload on dimension
static unsafe void ShowAddressAndData<T>(T[] data) where T : unmanaged
{
fixed (T* ptr = data)
{
Console.WriteLine((IntPtr)ptr);
//..
}
}

我想我找到了,如果你发现了太脆弱/可疑的东西,请评论:

Array data = new float[,] { { 4, 2 }, { 77, 3 } };
GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);
try
{
IntPtr address = handle.AddrOfPinnedObject();
float* ptr = (float*)address.ToPointer();
for (int i = 0; i < data.LongLength; ++i)
Console.WriteLine(ptr[i]);
}
finally
{
handle.Free();
}

最新更新