unsafe C#:如何从指向预先存在的内存位置的指针创建int[]
本文关键字:位置 内存 指针 创建 int 存在 unsafe | 更新日期: 2023-09-27 18:29:09
我在一个不安全的类中使用共享内存进行进程间通信。内存的一部分被保留来保存一个固定的int数组。
基本上,我有一个设置共享内存的方法。类似这样的东西:
private int* sizePtr;
private ???* arrayPtr;
void SetupMemory(byte *pointerToSharedMem)
{
this.sizePtr = (int*)pointerToSharedMem;
pointerToSharedMem += sizeof(int);
this.arrayPtr = (???*)pointerToSharedMem;
pointerToSharedMem += sizeof(int) * FixedSizeOfArray;
}
我需要如何声明指针才能使用属性
public int[] MyArray
{
get
{
return some magic with this.arrayPtr;
}
}
ETA:如果可能的话,我希望避免使用structs,当然也希望避免四处复制数据。我希望使用某种类型的强制转换构造来使用指向共享内存中数据的指针,这样数据就可以立即使用(即无需复制)。
实际上,我可以想出另一个答案。
不过,如果你使用不当,这很可能会变得很难看。
小心!
public unsafe class UnsafeArray
{
private readonly int* _start;
public readonly int Length;
public UnsafeArray(int* start, int enforceLength = 0)
{
this._start = start;
this.Length = enforceLength > 0 ? enforceLength : int.MaxValue;
}
public int this[int index]
{
get { return _start[index]; }
set
{
if (index >= this.Length)
{
throw new IndexOutOfRangeException();
}
_start[index] = value;
}
}
}
它需要是一个指针,还是可以复制数据?
如果可以的话,请查看这个链接
http://msdn.microsoft.com/en-us/library/aa330463(v=vs.71).aspx
在C#2.0及更高版本中,可以在unsafe
上下文中用嵌入式数组声明struct
:
namespace FixedSizeBuffers
{
internal unsafe struct MyBuffer
{
public fixed int fixedBuffer[128];
}
internal unsafe class MyClass
{
public MyBuffer myBuffer = default(MyBuffer);
}
internal class Program
{
static void Main()
{
MyClass myClass = new MyClass();
unsafe
{
// Pin the buffer to a fixed location in memory.
fixed (int* intPtr = myClass.myBuffer.fixedBuffer)
{
*intPtr = someIntValue;
}
}
}
}
}
http://msdn.microsoft.com/en-us/library/zycewsya(v=vs.100).aspx
没有比memcpy更好的了。
[DllImport("msvcrt.dll", EntryPoint = "memcpy", CallingConvention = CallingConvention.Cdecl, SetLastError = false)]
public static extern IntPtr memcpy(IntPtr dest, IntPtr src, UIntPtr count);
private static unsafe int[] GetArray(int* ptr, uint length)
{
var ints = new int[length];
fixed (int* pInts = ints)
{
memcpy(new IntPtr(pInts), new IntPtr(ptr), new UIntPtr(length));
}
return ints;
}