【问题标题】:Packing an int into a bitfield in C++在 C++ 中将 int 打包到位域中
【发布时间】:2011-07-30 06:05:04
【问题描述】:

我正在将一些代码从 ASM 转换为 C++,ASM 看起来像这样:

mov dword ptr miscStruct, eax

结构看起来像:

struct miscStruct_s {
  uLong brandID     : 8,
  chunks            : 8,
  //etc
} miscStruct;

是否有一种简单的两行方式来填充 C++ 中的结构? 到目前为止,我正在使用:

miscStruct.brandID = Info[0] & 0xff; //Info[0] has the same data as eax in the ASM sample.
miscStruct.chunks = ((Info[0] >> 8) & 0xff);

这一切都很好,但我必须填充这些位域结构中的大约 9-10 个,其中一些有 30 个奇数域。所以这样做最终会将 10 行代码变成 100+ 行代码,这显然不是那么好。

那么有没有一种在 C++ 中复制 ASM 的简单、干净的方法?

我当然试过“miscStruct = CPUInfo[0];”但不幸的是,C++ 不喜欢这样。 :(

error C2679: binary '=' : no operator found which takes a right-hand operand of type 'int'

..而且我无法编辑结构.

【问题讨论】:

  • 我最终使用了:*reinterpret_cast<int*>(&miscStruct) = Info[0];

标签: c++ bit-fields cpuid


【解决方案1】:

汇编指令的直译是这样的:

miscStruct=*(miscStruct_s *)&Info[0];

需要强制转换,因为 C++ 是一种类型安全的语言,而汇编程序不是,但复制语义是相同的。

【讨论】:

  • 根据您的示例,我最终倒退了。 *reinterpret_cast(&miscStruct) = Info[0];这有点时髦,但似乎可以胜任。
  • @Riley,不管怎样,两者的主要区别在于你认为哪一边是“真实的”长度。就我个人而言,我会选择内存中的对象 (miscStruct) 作为实际长度,因此您永远无法覆盖它,而在您的示例中,如果您稍后将 miscStruct 更改为只有一个字符,您将损坏您的记忆。
【解决方案2】:

memcpy (&miscStruct, &CPUInfo[0], sizeof (struct miscStruct_s));

应该有帮助。

或者干脆

int *temp = &miscStruct;
*temp = CPUInfo[0];

这里我假设 CPUInfo 的类型是 int 。您需要使用CPUInfo 数组的数据类型调整temp 指针类型。只需将结构的内存地址类型转换为数组的类型,然后使用指针将值分配给那里。

【讨论】:

  • memcpy (&miscStruct, , &CPUInfo[0], sizeof(miscStruct));
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-31
  • 2011-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-15
相关资源
最近更新 更多