【问题标题】:Accessing structure in structure through pointer通过指针访问结构中的结构
【发布时间】:2017-11-09 14:42:12
【问题描述】:

简要说明: 我通过指针写了一些东西来构造,但写了一些别的东西。我在 atollic true studio 8.1 工作,对 STM32F415RG MCU 进行编程。

最奇怪的是,即使我查看变量和表达式窗口,我也可以看到具有不同值的相同结构。 Same variable in two windows with different values

现在详细说明一下(我将简化很多内容以使其更具可读性)。 我定义了我的协议句柄类型:

typedef struct
{
  RS485DriverHandle master_rs485;
} EscomProtocolHandle;

我的RS485驱动句柄定义如下:

typedef struct
{
  UART_HandleTypeDef* uart_handle;
  TransceiverState transceiver_state;
  GPIO_TypeDef* dir_gpio;
  uint16_t      dir_pin;
} RS485DriverHandle;

我已将协议句柄创建为全局变量:

static EscomProtocolHandle hprot1;

我将它传递给我的协议初始化函数,该函数将指针作为参数处理:

Escom_Protocol_Init(&hprot1);

Init 函数将它传递给 RS485 驱动程序 init 函数,该函数将指向 RS485 句柄的指针作为参数(这个调用被简化了很多):

void Escom_Protocol_Init(EscomProtocolHandle* protocol_handle)
{
  RS485_Init(&protocol_handle->master_rs485)
}

RS485初始化函数设置默认值:

void RS485_Init(RS485DriverHandle* rs485_handle, UART_HandleTypeDef* uart_handle,
                GPIO_TypeDef* dir_gpio, uint16_t dir_pin)
{
  /* default = listening */
  rs485_handle->uart_handle = uart_handle;
  rs485_handle->dir_gpio = dir_gpio;
  rs485_handle->dir_pin = dir_pin;
  ReceiverOutputEnable(rs485_handle);
  rs485_handle->transceiver_state = kReceiving;
}

现在,如果我查看局部变量 rs485_handle,则这些值设置正确。但是如果我查看我的句柄 hprot1,值不匹配。即使 rs485_handle 的地址与 hprot1 句柄的 ma​​ster_rs485 成员的地址匹配。 P.S.:我没有弄乱上述任何结构的包装(#pragma pack),所以这应该不是问题。

【问题讨论】:

  • ReceiverOutputEnable(rs485_handle); 放置一个断点。检查调用前后的值。我在您的代码中没有发现任何问题,因此问题只能出在此调用中。
  • RS485_InitUART_HandleTypeDef* uart_handleGPIO_TypeDef* dir_gpio 的参数值是否定义在RS485_InitEscom_Protocol_Init 和/或堆分配之外可访问的范围内?跨度>
  • 注意:有时优先规则会搞乱我的意图。可以肯定的是,写:RS485_Init(&(protocol_handle->master_rs485))(确保取到正确的东西的地址)
  • 很难说,因为我们无法复制它。可能的原因是某种优化方式。可能是该变量在调试器中看起来很奇怪。您是在启用还是禁用优化的情况下进行调试?
  • 此外,如果有疑问,请怀疑 Eclipse。世界上所有的坏事都要归咎于它。 Eclipse 调试器因垃圾而臭名昭著。

标签: c pointers debugging structure handle


【解决方案1】:

知道了! 有一个看似不相关的头文件,其中有一个被打包的结构原型(1),并且在 structre 原型之后没有 #pragma pack() 将打包恢复为默认状态。因此,RS485DriverHandle 在不同的地方以不同的方式包装。在Escom_Protocol_InitRS485_Init 中,句柄结构的地址相同,但封装不同,例如GPIO_TypeDef* dir_gpio 成员的地址在Escom_Protocol_Init 中为0x200000D6,但在RS485_Init 中为0x200000D9。

【讨论】:

  • 你自己的答案得到了我的支持。你做了正确的调试工作,因为有时这是找到小虫子的唯一方法!
猜你喜欢
  • 2021-12-11
  • 1970-01-01
  • 2011-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多