unsafe C#: How can I create an int[] from a pointer to a preexisting memory location?

↘锁芯ラ 提交于 2021-02-19 05:50:08

问题


I am using shared memory for inter-process communication in an unsafe class. Part of the memory is reserved to hold a fixed array of int.

Basically, I have a method that sets up the shared memory. Something like this:

private int* sizePtr;

private ???* arrayPtr;

void SetupMemory(byte *pointerToSharedMem)

{

    this.sizePtr = (int*)pointerToSharedMem;
    pointerToSharedMem += sizeof(int);

    this.arrayPtr = (???*)pointerToSharedMem;
    pointerToSharedMem += sizeof(int) * FixedSizeOfArray;
}

How do I need to declare the pointer such that I can use a property

public int[] MyArray
{
    get
    {
       return some magic with this.arrayPtr;
    }
}

ETA: If possible, I would like to avoid structs and I definitely want to avoid copying data around. I was hoping for some kind of cast construct to use a pointer to the data in shared memory, such that the data can be used immediately (i.e. without copying).


回答1:


Actually, I can think of another answer.

This may very well get ugly if you don't use it just right, though.

Be careful!

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



回答2:


Does it need to be a pointer, or can you copy the data over?

If that's okay, then check out this link

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




回答3:


In C# 2.0 and above, a struct can be declared with an embedded array, in an unsafe context:

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




回答4:


Can't think of anything better than 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;
}


来源:https://stackoverflow.com/questions/9866231/unsafe-c-how-can-i-create-an-int-from-a-pointer-to-a-preexisting-memory-loca

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!