如果内存大小相等,如何将 C 结构体转换为另一种结构体类型?
我有 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 );
这可能吗?当前编译器打印一条“错误:请求转换为非标量类型”消息。
I have 2 matrix structs means equal data but have different form like these:
// 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;
Their memory sizes are equal. So I believe there is a way to convert these types without any pointer operations or copy like this:
// Implemented in external lib.
CATransform3D CATransform3DMakeScale (CGFloat sx, CGFloat sy, CGFloat sz);
Matrix m = (Matrix)CATransform3DMakeScale ( 1, 2, 3 );
Is this possible? Currently compiler prints an "error: conversion to non-scalar type requested" message.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
也许最好的解决方案是将两个结构组合成一个联合。如果您想以两种不同的方式解释相同的数据,那么这是显而易见的选择。另一种方法是使用指针强制转换,但这很丑陋,破坏了别名规则,并且可以隐藏编译器可能报告的错误。
Probably the best solution would be to combine your two structs into a union. If you want to interpret the same data in two different ways then it's the obvious choice. The alternative is to use pointer casts, but that's ugly, breaks aliasing rules, and can hide errors that might otherwise be reported by the compiler.
好吧,您可以像这样声明 CATransform3DMakeScale:
C 不会进行类型检查以确保您的减速与原始库匹配。如果内存布局相同,就可以工作。然而,这是不好的编码实践,您应该添加一个冗长的注释来证明您的行为是正确的。 ;-)
否则,没有办法解决这个问题:您必须使用指针或复制数据。这可行:
正如您所发现的,您不能直接转换结构。你也不能这样做:
因为 C 只允许你使用 &左值运算符。
Well, you could just declare CATransform3DMakeScale like this:
C doesn't type-check to make sure your deceleration matches the original library. If the memory layout is the same, it will work. However, it's bad coding practice and you should include a lengthy comment justifying your actions. ;-)
Otherwise, there's no way around it: you have to use pointers or copy the data. This would work:
As you've discovered, you can't cast the structure directly. You also can't do this:
because C only allows you to use the & operator on an l-value.