(.net) Есть ли внутренняя разница между структурами .net Explicit и объединениями c ++? - PullRequest
1 голос
/ 22 июля 2009

Вот в чем вопрос. Есть ли что-то, что вы можете сделать с объединениями c ++, чего не можете сделать с помощью явных структур c #

Ответы [ 3 ]

2 голосов
/ 22 июля 2009

C # явные структуры имеют некоторые проблемы, когда речь идет о ссылках / элементах размером с указатель.

Поскольку вы должны явно указать местоположение, но «sizeof (IntPtr)» не является константой времени компиляции (в отличие от C ++ sizeof), невозможно использовать члены размером с указатель в явных структурах, когда ваша сборка должна использоваться в как 32-битные, так и 64-битные процессы.

Также возможно использовать явные структуры для «преобразования» между ссылками и указателями:

[StructLayout(LayoutKind.Explicit)]
struct Test
{
    [FieldOffset(0)]
    public IntPtr ptr;
    [FieldOffset(0)]
    public string str;
}

Когда вы сделаете это, вашей сборке потребуется разрешение небезопасного кода; и есть проблема в том, что GC не будет знать, что делать со структурным содержимым - это GC-указатель, который должен отслеживать, или это просто целое число?

Итак, чтобы ответить на ваш вопрос: «Есть ли что-нибудь, что вы можете сделать с объединениями c ++, что вы не можете сделать с помощью явных структур c #?»

Да, в C ++ иногда полезно втиснуть два бита данных в младшие биты указателя. Это возможно, потому что два самых младших бита указателей всегда будут равны 0, когда указатель выровнен.

Черт возьми, если вы пишете двусвязный список из двух битов, вы даже можете хранить и указатели, и данные в 32 битах! («предыдущая ^ следующая ^ данные», см. связанный список XOR )

Тем не менее, вы не можете делать ничего подобного в C #, так как вы бы запутали GC.

1 голос
/ 22 июля 2009

Нет, не совсем. Атрибут LayoutKind - это способ объединения данных Marshall в объединения C ++. На самом деле он гораздо более гибкий, чем ключевое слово union в C ++, поскольку вы имеете полный контроль над макетом в C # с помощью структур.

0 голосов
/ 27 января 2012

Вы не можете перекрывать массив другого типа поверх данных. Например, вы не можете наложить байты [4] и int16, int16. Во время выполнения произойдет сбой.

...