C ++ to C #, static_cast в enum - PullRequest
2 голосов
/ 30 июля 2011

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

ar.GetFile()->Read(buf,sizeof(int));  
memmove(&x,buf,4);

pEBMA->before_after = static_cast<enum EBMA_Reserve>(x);
pEBMA->method       = static_cast<enum EBMA_Method>(x >> 4);

Вот некоторый связанный код.

struct EBMA_Data *pEBMA = &EBMA_data;

typedef CArray<struct EBMA_Data,struct EBMA_Data&> EBMA_data;

enum EBMA_Reserve
   {EBMA_DONT_RESERVE,
    EBMA_BEFORE,
    EBMA_AFTER
   };

enum EBMA_Method
   {EBMA_CENTER,
    EBMA_ALL_MATERIAL,
    EBMA_FRACTION,
    EBMA_RESERVE
   };


struct EBMA_Data
   {double reserved;
    double fraction;
    enum EBMA_Method method : 4;
    enum EBMA_Reserve before_after : 4;
   };

Я читал эту ветку здесь Приведите int к Enum в C # , но мой код не дает мне таких же результатов, как унаследованная программа.

Вот мой код на C #:

reserved = reader.ReadDouble();
fraction = reader.ReadDouble();
beforeAfter = (EBMAReserve)Enum.ToObject(typeof(EBMAReserve), x);
method = (EBMAMethod)Enum.ToObject(typeof(EBMAMethod), (x >> 4));

У меня есть проблема с порядком байтов, поэтому я обращаюсь к порядку байтов вот так.

public override double ReadDouble()
        {
            byte[] b = this.ConvertByteArrayToBigEndian(base.ReadBytes(8));
            double d = BitConverter.ToDouble(b, 0);
            return d;
        }
 private byte[] ConvertByteArrayToBigEndian(byte[] b)
        {
            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(b);
            }

            return b;
        }

Тогда я подумал, что, возможно, проблема с порядком байтов все еще отбрасывает меня, так что вот еще одна попытка:

byte[] test = reader.ReadBytes(8);
Array.Reverse(test);
int test1 = BitConverter.ToInt32(buffer, 0);
int test2 = BitConverter.ToInt32(buffer, 4);
beforeAfter = (EBMAReserve)test1;
method = (EBMAMethod)test2;

Надеюсь, я достаточно подробно рассказал о том, что я пытаюсь сделать.

EDIT:

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

byte[] temp = reader.ReadBytes(4);
byte b = temp[0];

res = (EBMAReserve)(b & 0x0f);
meth = (EBMAMethod)(b >> 4);

1 Ответ

2 голосов
/ 30 июля 2011

РЕДАКТИРОВАТЬ: на самом деле размер структуры EBMA_Data равен 17 байтам.

struct EBMA_DATA
{
  double reserved; //(8 bytes)
  double fraction; //(8 bytes)
  enum EBMA_Method method : 4; //(this is packed to 4 bits, not bytes)
  enum EMBA_Reserve before_after : 4; //(this too, is packed to 4 bits)
}

, поэтому код чтения должен выглядеть примерно так:

 EBMA_Data data = new EBMA_Data;
 data.reserved = reader.ReadDouble();
 data.fraction = reader.ReadDouble();
 byte b = reader.ReadByte();
 data.method = (EBMAMethod)(b >> 4);
 data.before_after = (EBMAReserve)(b & 0x0f);

Не уверен на 100%, но похоже, что код, который выполняет сдвиг x >> 4 байтов, может быть основной проблемой, которую упускают из виду.Если EBMAReserve - это младшие 4 бита x, а EBMAMethod - старшие 4 бита, может быть, этот код будет работать?

 EBMAReserve res = (EBMAReserve)(x & 0x0f);
 EBMAMethod meth = (EBMAMethod)(x >> 4);

Я думаю, что это означает : 4 после перечисленийв структуре он упаковывает два перечисления в структуру как один байт вместо 2 байтов.

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