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

Posted

技术标签:

【中文标题】* 类型的 C 参数与 * 类型的参数不兼容【英文标题】:C argument of type * is incompatible with parameter of type * 【发布时间】:2021-07-22 05:02:44 【问题描述】:

我正在尝试在 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,0,0,0,0,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, &keyboardhid, sizeof (keyboardhid));
        HAL_Delay (1000);

【问题讨论】:

信息很清楚。您在需要uint8_t * 的地方使用keyboardhid *。您的编译器很有帮助并发出诊断信息。 如果你确定没关系你可以试试演员USBD_HID_SendReport(&hUsbDeviceFS, (uint8_t*)&keyboardhid, sizeof (keyboardhid));...但不要告诉任何人我什至建议过这个。再次强调一下:只有在确定没问题的情况下才这样做 感谢您的回答。它有效,对我来说就足够了 一个在视频中教编程的人不值得被当真。 【参考方案1】:

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

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

你可以:

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

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

    使用联合。

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

并将u.bytes 传递给USBD_HID_SendReport()

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

【讨论】:

以上是关于* 类型的 C 参数与 * 类型的参数不兼容的主要内容,如果未能解决你的问题,请参考以下文章

“void(*)(int wall)”类型的 C++ 参数与“int”类型的参数不兼容

“char *”类型的参数与“LPWSTR”类型的参数不兼容

参数与同一类型的参数不兼容

E0167 “CHAR *”类型的参数与“const wchar_t *”类型的参数不兼容

“const char *”类型的参数与“Person”类型的参数不兼容

Nil与预期的参数类型UIViewAnimationOptions不兼容