我有2个矩阵结构意味着相同的数据但具有不同的形式:
// Matrix type 1.
typedef float Scalar;
typedef struct { Scalar e[4]; } Vector;
typedef struct { Vector e[4]; } Matrix;
// Matrix type 2 (you may know this if you're iPhone developer)
// Defines CGFloat as float for simple description.
typedef float CGFloat;
struct CATransform3D
{
CGFloat m11, m12, m13, m14;
CGFloat m21, m22, m23, m24;
CGFloat m31, m32, m33, m34;
CGFloat m41, m42, m43, m44;
};
typedef struct CATransform3D CATransform3D;
他们的内存大小相等。所以我相信有一种方法可以转换这些类型,而无需任何指针操作或复制,如下所示:
// Implemented in external lib.
CATransform3D CATransform3DMakeScale (CGFloat sx, CGFloat sy, CGFloat sz);
Matrix m = (Matrix)CATransform3DMakeScale ( 1, 2, 3 );
这可能吗?目前编译器打印“错误:转换为非标量类型请求”消息。
答案 0 :(得分:16)
可能最好的解决方案是将两个结构组合成一个联合体。如果您想以两种不同的方式解释相同的数据,那么这是显而易见的选择。另一种方法是使用指针强制转换,但这很难看,打破别名规则,并且可以隐藏编译器可能报告的错误。
typedef float Scalar;
typedef struct { Scalar e[4]; } Vector;
typedef struct { Vector e[4]; } Matrix;
struct CATransform3D
{
CGFloat m11, m12, m13, m14;
CGFloat m21, m22, m23, m24;
CGFloat m31, m32, m33, m34;
CGFloat m41, m42, m43, m44;
};
typedef struct CATransform3D CATransform3D;
typedef union
{
CATransform3D t;
Matrix m;
} UMatrix;
CATransform3D CATransform3DMakeScale (CGFloat sx, CGFloat sy, CGFloat sz);
UMatrix um;
um.t = CATransform3DMakeScale ( 1, 2, 3 );
//
// now you can just use um.m when you need to refer to the Matrix type...
//
答案 1 :(得分:1)
好吧,您可以像这样声明CATransform3DMakeScale:
Matrix CATransform3DMakeScale (CGFloat sx, CGFloat sy, CGFloat sz);
C不进行类型检查以确保减速度与原始库匹配。如果内存布局相同,它将起作用。然而,这是糟糕的编码实践,你应该包括一个冗长的评论来证明你的行为。 ; - )
否则,没有办法绕过它:你必须使用指针或复制数据。这可行:
CATransform3D m3d = CATransform3DMakeScale ( 1, 2, 3 );
Matrix m;
memcpy(&m, &m3d, sizeof m);
正如您所发现的,您无法直接投射结构。你也做不到这个:
Matrix m = *(Matrix*) &CATransform3DMakeScale ( 1, 2, 3 );
因为C只允许你使用&运算符在l值上。