不安全的C#:如何从指向预先存在的内存位置的指针创建一个int []?

时间:2012-03-26 03:22:11

标签: c# unsafe

我在不安全的类中使用共享内存进行进程间通信。 部分内存保留用于保存固定的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: 如果可能的话,我想避免结构,我绝对想避免复制数据。我希望某种类型的强制转换构造能够使用指向共享内存中数据的指针,这样数据就可以立即使用(即无需复制)。

4 个答案:

答案 0 :(得分:3)

实际上,我可以想到另一个答案。

如果你不恰当地使用它,这可能会很难看。

小心!

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;
        }
    }
}

答案 1 :(得分:0)

是否需要指针,还是可以复制数据?

如果没关系,请查看此链接

http://msdn.microsoft.com/en-us/library/aa330463(v=vs.71).aspx

答案 2 :(得分:0)

在C#2.0及更高版本中,可以在struct上下文中使用嵌入数组声明unsafe

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

答案 3 :(得分:0)

想不出比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;
}