MSDN.WhiteKnight - Stack Overflow answers
Ответ на "Аналог PtrToStructure для классов"
Answer 1004583
Создание указателя на класс - невозможно (ошибка CS0208)
Создание указателя на класс невозможно напрямую, так как он управляется сборщиком мусора и может быть перемещен в памяти. Однако, класс можно закрепить с помощью Pinned GCHandle и получить указатель на закрепленный объект - но для этого класс должен состоять только из простых типов и иметь атрибут
[StructLayout(LayoutKind.Sequential)]
(несмотря на название, его можно применить и к классу).А Marshal.PtrToStructure также рассчитан только на структуры
Строго говоря, это не так. Marshal.PtrToStructure работает и c классами, если они удовлетворяют тем же условиям: состоят только из простых типов и имеют атрибут
[StructLayout(LayoutKind.Sequential)]
.Вот пример использования указателей на класс:
[StructLayout(LayoutKind.Sequential)] class MyClass { public int A; public override string ToString() { return A.ToString(); } } static void Main(string[] args) { MyClass my0 = new MyClass { A = 2 }; MyClass my1 = new MyClass { A = 3 }; //закрепим объекты в памяти GCHandle h0 = GCHandle.Alloc(my0, GCHandleType.Pinned); GCHandle h1 = GCHandle.Alloc(my1, GCHandleType.Pinned); try { //получим адреса объектов IntPtr ptr0 = h0.AddrOfPinnedObject(); IntPtr ptr1 = h1.AddrOfPinnedObject(); //убедимся, что адреса реальные и по ним можно считать данные (первое поле класса) Console.WriteLine("Значение по ptr0: " + Marshal.ReadInt32(ptr0)); Console.WriteLine("Значение по ptr1: " + Marshal.ReadInt32(ptr1)); IntPtr tmp = ptr0; ptr0 = ptr1; ptr1 = tmp; my0 = Marshal.PtrToStructure<MyClass>(ptr0); my1 = Marshal.PtrToStructure<MyClass>(ptr1); Console.WriteLine("my0.A=" + my0); Console.WriteLine("my1.A=" + my1); } finally { //вернем объекты в управление GC h0.Free(); h1.Free(); } Console.ReadLine(); }
В отличие от принятого ответа, здесь используется указатель на сами данные класса, а не на заголовок объекта. Также при вызове Marshal.PtrToStructure создается новая копия объекта, вместо разыменования указателя на существующий объект.
Content is retrieved from StackExchange API.
Auto-generated by ruso-archive tools.