将一个C结构铸造成另一个

时间:2010-10-22 10:29:17

标签: c casting struct

我有两个相同(但命名不同)的C结构:

typedef struct {
      double x;
      double y;
      double z;
} CMAcceleration;


typedef struct {
    double x;
    double y;
    double z;   
} Vector3d;

现在我想将一个CMAcceleration变量赋给一个Vector3d变量(复制整个结构)。我怎么能这样做?

我尝试了以下操作但得到了这些编译器错误:

vector = acceleration;           // "incompatible type"
vector = (Vector3d)acceleration; // "conversion to non-scalar type requested"

当然,我可以单独设置所有成员:

vector.x = acceleration.x;
vector.y = acceleration.y;
vector.z = acceleration.z;

但这似乎很不方便。

什么是最好的解决方案?

9 个答案:

答案 0 :(得分:42)

这是你唯一的解决方案(除了将其包装成一个函数):

vector.x = acceleration.x;
vector.y = acceleration.y;
vector.z = acceleration.z;

你可以实际投射它,像这样(使用指针)

Vector3d *vector = (Vector3d*) &acceleration;

但这不在规范中,因此行为取决于编译器,运行时和大绿地怪物。

答案 1 :(得分:16)

您可以使用指针进行类型转换;

vector = *((Vector3d *) &acceleration);

答案 2 :(得分:6)

您可以使用实用程序功能:

void AccelerationToVector( struct CMAcceleration* from, struct Vector3d* to )
{
     to->x = from->x;
     to->y = from ->y;
     to->z = from->z;
}

答案 3 :(得分:5)

memcpy(&vector, &acceleration, sizeof(Vector3d));

请注意,如果内存中结构的物理布局相同,则此方法有效。但是,正如@Oli指出的那样,编译器没有义务确保这一点!

答案 4 :(得分:5)

为什么不使用。

typedef CMAcceleration Vector3d;

(而不是创建一个全新的结构)

在这种情况下vector = acceleration;编译得很好。

答案 5 :(得分:1)

安全(虽然有点复杂)的方法是使用联合:

union { CMAcceleration a, Vector3d v } tmp = { .a = acceleration };
vector = tmp.v;

当被访问的成员不是最后一个成员时,将重新解释值(自C99起)。在这种情况下,我们设置加速度然后我们访问向量,因此重新解释加速度。

这是NSRectToCGRect函数的实现方式,例如。

答案 6 :(得分:1)

这可以通过 union

轻松实现
typedef struct {
      double x;
      double y;
      double z;
} CMAcceleration;

typedef struct {
    double x;
    double y;
    double z;
} Vector3d;

typedef union {
    CMAcceleration acceleration;
    Vector3d vector;
} view;

int main() {
    view v = (view) (Vector3d) {1.0, 2.0, 3.0};
    CMAcceleration accel = v.acceleration;
    printf("proof: %g %g %g\n", accel.x, accel.y, accel.z);
}

答案 7 :(得分:1)

使用C99的实用程序功能的另一个版本:

static inline struct Vector3d AccelerationToVector(struct CMAcceleration In)
{
    return (struct Vector3d){In.x, In.y, In.z};
}

打开编译器优化功能(例如-Os),在调用时应该完全没有目标代码。

答案 8 :(得分:0)

您可以使用指针创建联合,从而避免复制数据。

示例:

struct Ocp1SyncHeader
{
    aes70::OCP1::OcaUint8 syncVal;          
    aes70::OCP1::Ocp1Header header;
};

struct convertToOcp1SyncHeader
{
    union
    {
        Ocp1SyncHeader* data;
        const uint8_t* src;
    };
    convertToOcp1SyncHeader& operator=(const uint8_t* rvalue) 
    { 
      src = (const uint8_t*)rvalue; 
      return *this; 
    }
};

**这样访问:

convertToOcp1SyncHeader RecvData;
RecvData = src;  // src is your block of data that you want to access

**这样的访问成员:

RecvData.data.header