* 类型的 C 参数与 * 类型的参数不兼容

问题描述

我正在尝试在 STM32 板上制作 HID。但是我遇到了下一个问题:我不明白我的错误在哪里,我传递了一个指向包含报告函数数据的结构的指针,但是当我尝试编译代码时,我收到下一条消息:“keyboardHID *”类型的参数不兼容使用“uint8_t *”类型的参数,我以与此视频https://www.youtube.com/watch?v=tj1_hsQ5PR0中的人相同的方式编写代码。在他的例子中,这不是一个严重的错误代码可以编译。

我的结构:

typedef struct
{
    uint8_t MODIFIER;
    uint8_t RESERVED;
    uint8_t KEYCODE1;
    uint8_t KEYCODE2;
    uint8_t KEYCODE3;
    uint8_t KEYCODE4;
    uint8_t KEYCODE5;
    uint8_t KEYCODE6;
} keyboardHID;

keyboardHID keyboardhid = {0,0}; // it should be like this,not differently

修改结构元素并向计算机发送报告的代码

keyboardhid.MODIFIER = 0x02;  // left Shift
        keyboardhid.KEYCODE1 = 0x04;  // press 'a'
        keyboardhid.KEYCODE2 = 0x05;  // press 'b'
        USBD_HID_SendReport(&hUsbDeviceFS,&keyboardhid,sizeof (keyboardhid));
        HAL_Delay (50);
        
        keyboardhid.MODIFIER = 0x00;  // shift release
        keyboardhid.KEYCODE1 = 0x00;  // release key
        keyboardhid.KEYCODE2 = 0x00;  // release key
        USBD_HID_SendReport(&hUsbDeviceFS,sizeof (keyboardhid));
        HAL_Delay (1000);

解决方法

C 只允许隐式指针转换为 void*。 类型 uint8_tkeyboardHID 不兼容,它们的指针也不兼容。 我假设 uint8_tunsigned char 但 C 标准不需要它。

通常,直接处理内存的函数应该使用 void* 之类的 memcpy()memset(),但看起来 USBD_HID_SendReport() 没有遵循此约定。

您可以:

  1. &keyboardhid 转换为 uint8_t*。这是安全的,因为字符类型的对齐要求最少。此外,字符是严格别名规则的明确例外。

  2. 使用 &keyboardhid.MODIFIER。 C 标准要求结构的地址与其第一个元素的地址相同。 IMO,这是最晦涩的方式。

  3. 使用联合。

union {
  keyboardHID keyboardhid;
  uint8_t bytes[sizeof(keyboardHID)];
} u;

然后将 u.bytes 传递给 USBD_HID_SendReport()

我会选择选项 1,因为它最简单且安全。如果必须将 keyboardhid 强制转换为 void* 以外的其他内容或指向字符类型的指针(即 uint32_t*),则选项 3 将是最佳选择。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...