来自 Ua_Variant 的 C 类型转换

问题描述

我试图了解以下代码中的类型转换在做什么

UA_Variant Variant; 
Int32_t Variable; 

variable = *(int32_t *) Variant.data; 
printf("%d",variable);

这是 UA_Variant 的结构

typedef struct 
{
    const UA_DataType *type;      /* The data type description */
    UA_VariantStorageType storageType;
    size_t arrayLength;           /* The number of elements in the data array */
    void *data;                   /* Points to the scalar or array data */
    size_t arrayDimensionsSize;   /* The number of dimensions */
    UA_UInt32 *arrayDimensions;   /* The length of each dimension */
} UA_Variant;

这一行发生了什么

variable = *(int32_t *) Variant.data; 

是否将 Variant 中的数据类型转换为 int32_t,然后将其指针放入变量中,如果是这样,为什么我可以打印出存储在变量中的值?

解决方法

让我们分多个步骤解开这个语句:*(int32_t *) Variant.data

首先,我们有 Variant.data,根据 void* 结构,它是一个 UA_Variant。这意味着它只是一个包含内存地址的数字。

然后,使用 (int32_t *)void* 转换为 int32_t*Variant.data 指向的数据随后将被解释为指向 int32_t 类型数据的指针。 我坚持解释而不是强制转换。

最后,您使用 * 运算符取消引用它。因此,变量 variable 包含由 Variant.data 指向的数据,解释为有符号的 32 位值。这意味着,如果 Variant.data 指向的数据是其他一些数据类型,例如 float s,则变量中的结果值看起来是随机的,并且取决于未定义的行为。这是因为不同的平台以不同的方式实现每种数据类型。

由于这个变量是一个值,你可以像其他任何变量一样打印它。

,

您的 data 结构的 UA_Variant 成员被定义为 void*,这意味着它指向一个对象未指定类型。这种“空指针”不能解除引用。

因此,如果您的 data 的特定 Variant 成员指向一个将被视为 int32_t 类型的对象的对象,则该指针本身 必须首先转换为正确的指针类型 (int32_t*);然后,它可以被取消引用。

variable = *(int32_t *) Variant.data; 行可能通过添加一些括号更容易理解。这是等效的代码:

variable = *( (int32_t *)(Variant.data) );