【问题标题】:C type casting from a Ua_Variant来自 Ua_Variant 的 C 类型转换
【发布时间】:2021-04-04 15:37:42
【问题描述】:

我试图了解在以下代码中类型转换的作用

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,然后将其指针放入变量中,如果是,为什么我可以打印出存储在变量中的值?

【问题讨论】:

    标签: c pointers open62541


    【解决方案1】:

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

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

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

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

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

    【讨论】:

    • 谢谢,我现在明白了。
    【解决方案2】:

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2011-04-06
      • 2019-10-28
      • 1970-01-01
      • 2013-02-23
      • 1970-01-01
      • 2011-06-13
      • 1970-01-01
      • 2012-02-23
      • 1970-01-01
      相关资源
      最近更新 更多