C++对于 C#,static_cast 为枚举

发布于 2024-11-26 20:02:41 字数 2199 浏览 5 评论 0原文

我正在尝试将一些 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);

I'm trying to convert a bit of VC 6.0 C++ code to C#. Specifically, I'm parsing through a binary dat file and I've run into a problem converting this bit of code:

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);

Here is some related code.

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;
   };

I've read this thread here Cast int to Enum in C#, but my code isn't giving me the same results as the legacy program.

Here is some of my code in C#:

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

I do have an endianness problem so I am reversing the endianness like so.

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;
        }

So then I thought that maybe the endianness issue was still throwing me off so here is another attempt:

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;

I hope I've given enough details about what I'm trying to do.

EDIT:

This is how I solved my issue, apparently the values I needed were stored in the first byte of a 4 byte segment in the binary file. This is in a loop.

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

时光瘦了 2024-12-03 20:02:41

编辑:实际上看起来 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 个字节打包到结构中。

EDIT: It actually looks like the structure size of EBMA_Data is 17 bytes.

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)
}

so your read code should look something more like this:

 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);

Not 100% sure, but it looks like the code that does the shift x >> 4 bytes may be the underlying issue that's being overlooked. If the EBMAReserve is the lower 4 bits of x and EBMAMethod is the top 4 bits, maybe this code would work?

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

I think that is what the : 4 means after the enumerations in the struct, it's packing the two enums into the structure as a single byte instead of 2 bytes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文