问题
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