C ++ Преобразование в C #

У меня следующая ситуация:

struct object1  {

bool a:1;
bool b:1;
uint8_t c:2;
bool d:1;
abc  e:3;

uint16_t header;
uint8_t footer;
uint8_t mid[4];
}

Возможно, я не знаю синтаксис, но в C # играть с битами не так просто, как в C ++. Я использовал классы BitArray и BitConverter для создания методов для заполнения данных, но столкнулся с проблемой:

object1 * rqr = (object1  *) &Msg.Data[2];

В основном они приводят объект к массиву байтов. Каждый поиск, который я проводил, кричит по сериализации, но чтобы действительно преобразовать вышеуказанную строку, у меня не может быть никаких дополнительных метаданных или чего-либо еще.

Я действительно хочу создать указатель на место в памяти и «привести» это место к указанному объекту. Это возможно? Если нет, есть ли решение этой проблемы? Я не могу себе представить, что битовые манипуляции на этом уровне полностью исключены. Я бы по умолчанию для меня просто не зная, прежде чем принять это.

Редактировать::
Я понимаю, что C # не позволяет указатели на типы управления. Я спрашиваю, есть ли способ сказать:

Byte[] ayData = new Byte[8];
ObjectOfSize8 nObject =  (ObjectOfSize8)ayData;

Я понимаю, что вышесказанное не сработает, но есть ли в языке что-то, что позволит приводить данные, если вы достаточно умны, чтобы понимать размеры памяти объектов?

1

Решение

Вы не можете делать то, что просите, с приведением типов в C #. Я подозреваю, что самый простой способ сделать то, что вам нужно, это закрепить структуру C #. Затем у вас есть IntPtr, который вы можете использовать с Marshal.Copy для копирования в и из байтового массива.

Что касается битовых полей, ими нужно будет управлять с помощью операций побитового сдвига, побитового ИЛИ и побитового И.

1

Другие решения

Вы можете решить проблему с битовым полем с помощью структуры, которая обрабатывает битовый сдвиг и маскировку для вас:

[StructLayout(LayoutKind.Sequential, Size=1)]
public struct BitField8
{
private byte _bits;

private static readonly byte[] Masks = new byte[] { 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff };
public BitField8(int val)
{
_bits = (byte) val;
}

public byte Get(int bit, int length = 1)
{
int shift = bit + length - 1;
return (byte) ((_bits >> shift) & Masks[length-1]);
}

public void Set(int bit, int length, int val)
{
int mask = Masks[length-1];
int shift = bit + length - 1;
val = (val & mask) << shift;
mask = ~(mask << shift);
_bits = (byte)((_bits & mask) | val);
}
}

Итак, в вашем примере:

bool a:1;
bool b:1;
uint8_t c:2;
bool d:1;
abc  e:3;

Вы бы установили a позвонив Set(0, 1, 1) (установите значение 1).

Дать c значение 3, вы бы назвали Set(3, 2, 3), (c занимает биты 2 и 3).

Это в основном дублирует функциональность битовых полей C ++, хотя я допускаю, что у меня неправильный порядок битов. Я действительно не знаю, поставил ли компилятор C ++ a в бите 0 или в бите 7.

Вы можете сделать что-то подобное с 16-битными, 32-битными и 64-битными битовыми полями.

Итак, ваша структура будет содержать:

BitField8 myBitfield;
2

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector