【问题标题】:map struct with array variable to struct with explicit variables将带有数组变量的结构映射到带有显式变量的结构
【发布时间】:2022-01-18 18:59:04
【问题描述】:

假设我从分包商那里得到了以下struct A 定义:

struct A {
  int var0;
  int var1;
  int var2;
};

我无法对其进行任何更改,但我必须使用此结构来调用分包商 API。在我的计算组件中,我将使用更通用的版本,称为struct B

struct B {
  int var[3];
  int other_vars[3];
  // [...]
};

鉴于这些,我正在寻找一种简单的方法来将数组 var 从我更通用的 struct B 映射到 struct A 的显式变量声明。

目前的实现很简单

a.var0 = b.var[0];
a.var1 = b.var[1];
a.var2 = b.var[2];

如果struct A 得到更新,它会生成一个非常大的映射文件,并且将来可能会失败。

可能的解决方案:

我想过memcpy之类的东西,但我认为那很不安全..

#define MAP(from, to, var) \
    std::memcpy(&to.var##0, &from.var, sizeof(from.var));

MAP(b, a, var);

Online GDB with this example

旁注:

  • 结构比这里显示的要大得多。以这种方式定义了许多具有更高索引的不同变量。
  • 由于struct A的代码是由分包商生成的(我们得到了生成的.h文件),我不能保证变量的顺序是正确的,并且不会被其他变量中断。这就是为什么我认为我可能的解决方案还不够好。

【问题讨论】:

  • 如果两个结构都正确对齐/填充memcpy() 应该可以工作吗?
  • 虽然struct Aint 成员可能会在内存中相互跟随,但不能保证。成员之间可能有填充。
  • 如果A是生成代码,是不是也生成映射?
  • 你试过 std::bit_cast 吗?
  • 除非A结构包含复杂的声明,为什么不创建自己的脚本或预处理器类型的程序来读取和解析结构,并生成用于映射/复制其他结构到@987654339的代码@结构?

标签: c++ arrays c++11 vector struct


【解决方案1】:

只要结构 A 的成员以相同的顺序映射到结构 B::var,memcpy 就是最好的方法。 B 两个结构都是“标准布局”类型,它们保证占用连续的存储字节。

来自 C++ 标准:

普通可复制或标准布局类型的对象应占用连续字节的存储空间。

处理任何可能使此过程不安全的潜在填充问题;静态断言可用于确保一切按预期排列。

#include <type_traits>

struct A {
  int var0;
  int var1;
  int var2;
  // int var3; // Adding this variable will cause static_assert to fail.
};

struct B {
  int var[3];
  int other_vars[3];
  // [...]
};
// Note: for B to be trivially-copyable or standard-layout, all the members must also be.
static_assert( std::is_trivially_copyable<A>::value);
static_assert( std::is_trivially_copyable<B>::value);
static_assert( std::is_standard_layout<A>::value);
static_assert( std::is_standard_layout<B>::value);
static_assert(sizeof(A) == sizeof(B::var), "Incompatible mapping to subcontractor.");

同样,这仅在结构 A 不发生变化时才有效,因此 A::var0 现在应该映射到 B::var[1] 或一些不连续的顺序。

【讨论】:

    猜你喜欢
    • 2012-11-20
    • 1970-01-01
    • 1970-01-01
    • 2011-01-27
    • 2018-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-11
    相关资源
    最近更新 更多