我正在尝试将一些VC 6.0 C ++代码转换为C#。具体来说,我正在解析二进制dat文件,我遇到了转换这段代码的问题:
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;
};
我在这里阅读了这个帖子Cast int to Enum in 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;
我希望我已经提供了足够的细节,我正在尝试做什么。
修改
这就是我解决问题的方法,显然我需要的值存储在二进制文件中4字节段的第一个字节中。这是一个循环。
byte[] temp = reader.ReadBytes(4);
byte b = temp[0];
res = (EBMAReserve)(b & 0x0f);
meth = (EBMAMethod)(b >> 4);
答案 0 :(得分:2)
编辑:实际上看起来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%肯定,但看起来执行shift x >> 4
字节的代码可能是被忽略的潜在问题。如果EBMAReserve
是x的低4位而EBMAMethod
是前4位,那么这段代码可能有效吗?
EBMAReserve res = (EBMAReserve)(x & 0x0f);
EBMAMethod meth = (EBMAMethod)(x >> 4);
我认为这就是: 4
在结构中的枚举之后的含义,它将两个枚举打包成结构为单个字节而不是2个字节。