Влияет ли изменение структуры в C # на неуправляемую память? - PullRequest
9 голосов
/ 02 сентября 2010

Моя внутренняя реакция - нет, потому что управляемая и неуправляемая память различны, но я не уверен, что .NET Framework что-то делает с Marshaling за кулисами.

Я считаю, что происходит: когдаполучение структуры из моей неуправляемой DLL, это то же самое, что и вызов вызывает получение IntPtr, а затем использует его и класс Marshal для копирования структуры в управляемую память (и изменения, вносимые в структуру в управляемой памяти, не всплывают).

Кажется, я не могу найти это нигде в MSDN.Любые ссылки приветствуются.

Вот как выглядит мой код:

[DllImport("mydll.dll", BestFitMapping=false, CharSet=CharSet.Ansi)]
private static extern int GetStruct(ref MyStruct s);

[StructLayout(LayoutKind.Sequential, Pack=0)]
struct MyStruct
{
     public int    Field1;
     public IntPtr Field2;
}

public void DoSomething()
{
      MyStruct s = new MyStruct();
      GetStruct(ref s);

      s.Field1 = 100; //does unmanaged memory now have 100 in Field1 as well?
      s.Field2 = IntPtr.Zero; //does unmanaged memory now have a NULL pointer in field Field2 as well?
}

Ответы [ 2 ]

8 голосов
/ 02 сентября 2010

Нет, маршаллер P / Invoke скопировал значения элементов неуправляемой структуры в управляемую версию структуры. В общем, управляемая версия структуры никоим образом не совместима с неуправляемой версией структуры. Структура памяти не может быть обнаружена, то, что CLR использует для изменения порядка полей , чтобы уменьшить структуру. Маршалинг необходим, у вас есть для создания копии.

Изменение структуры невозможно с данной сигнатурой функции, так как вы позволяете заполнить память, которая передается ей. Сама функция уже копирует структуру. Однако вы можете указать значение Field2, так как оно является необработанным указателем. Если это указывает на структуру, то соберите ее с помощью Marshal.PtrToStructure(). Измените управляемую копию и скопируйте ее обратно в неуправляемую память с помощью Marshal.StructureToPtr(). Или получить к нему доступ непосредственно с помощью Marshal.ReadXxx () и WriteXxx ().

0 голосов
/ 23 сентября 2010

CSharp Language Specification.doc pg 26

Конструкторы Struct вызываются с новым оператором, но это не означает, что выделяется память.Вместо того, чтобы динамически размещать объект и возвращать ссылку на него, конструктор структуры просто возвращает само значение структуры (обычно во временном местоположении в стеке), и это значение затем копируется по мере необходимости.

Поскольку в бэк-хранилище 'struct' нет ничего особенного, поэтому не следует ожидать, что за назначениями членов будут выполняться анонимные операции маршалинга.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...