На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: maxim84_
  
> StructLayoutAttribute , Управление размещением полей в объектах
    Как известно, Just InTime компилятор выполняет ряд оптимизаций
    для повышения быстродействия приложения. Одной из таких оптимизаций
    является порядка размещения полей типа. Так,
    CLR может упорядочить поля таким образом, что ссылки на объекты
    окажутся в одной группе, а поля данных и свойства, выровненные и
    упакованные, - в другой.

    Но порой, такое поведение компилятора может приводить к неожиданным
    результатам (например при работе с unmanaged кодом). Для избежания
    "неприятных" ситуаций существуют специальный атрибут при описании
    классов или структур. Чтобы разрешить CLR устанавливать порядок полей
    следует указать атрибут System.Runtime.InteropServices.StructLayoutAttribute
    LayoutKind.Auto, чтобы сохранить порядок, указанный программистом, -
    LayoutKind.Sequental. По-умолчанию же, компилятор C# LayoutKindAuto для
    ссылочных типов (классов) и LayoutKindSequental для значимых типов
    (структур). Однако, если же ваш значимый тип не будет работать с
    unmanaged кодом, то имеет смысл изменить значение по-умолчанию и
    разрешить CLR упорядочить поля:

    ExpandedWrap disabled
      using System;
      using System.Runtime.InteropServices;
      // разрешаем CLR упорядочивание полей
      [StructLayout(LayoutKind.Auto)]
      struct my_Point
      {
        int x,y;
      }


    Кроме того, существует еще один атрибут, предоставляющий интересные
    возможности. Так, задав атрибут LayoutKind.Explicit, можно явно
    указывать компилятору смещения тех или иных полей с помощью
    FieldOffset(Int32) в байтах от начала экземпляра. С помощью
    данного метода можно добиться эффекта, подобного uninon из Си или
    Record-Case, Absolute из Паскаля. Например:
    ExpandedWrap disabled
      using System;
      using System.Runtime.InteropServices;
      // явно зададим смещения полей
      [StructLayout(LayoutKind.Explicit)]
      struct LikeUninon
      {
        [FieldOffset(0)] Int32 X;
        [FieldOffset(0)] Int16 X1;
        [FieldOffset(2)] Int16 X2;
      }


    Но не следует перекрывать ссылочные поля значимыми и наоборот.
    Кроме того, все пересекающиеся байты должны быть доступны через
    открытые поля.
    Сообщение отредактировано: e-moe -
    0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
    0 пользователей:


    Рейтинг@Mail.ru
    [ Script execution time: 0,0150 ]   [ 15 queries used ]   [ Generated: 23.04.24, 07:37 GMT ]