C++ 没有从 'int*' 到 'uint16_t* {a ka short unsigned int*}' 的已知转换

C++ no known conversion from 'int*' to 'uint16_t* {a ka short unsigned int*}'

我正在尝试 运行 为 STM32 上的 Arduino 设计的磁力计代码。为 Arduino 编译时,我没有收到任何错误,并且从传感器读取的值已签名。为 STM 编译时出现错误:"no known conversion for argument 1 from 'int*' to 'uint16_t* {aka short unsigned int*}'".

这非常有道理,但从这里到哪里去呢?

目标是获得与普通 Arduino 开发板相同的结果。

图书馆:https://github.com/mechasolution/Mecha_QMC5883

您可以使用 C 风格强制转换,如果编译器对此抱怨,转换为 void * 然后转换为所需的类型,这将关闭它。但这些抱怨很可能是有道理的。 int 和 uint16_t 可能宽度不一样,那么你希望通过这种方式乱用指针来实现什么?

因为stm32上的int是32位的,AVR上的int是16位长的。当您将指向 int 的指针传递给采用指向 uint16_t 的指针的函数时,无法进行转换。为什么?

当您取消引用指针时,对取消引用的指针的任何赋值仅写入 2 个字节,而原始类型为 4 个字节。所以2个字节不受影响。

示例

void foo(uint16_t *ptr) {
    *ptr = 0x1122
}

int val = 0x0feeddcc;

foo((uint16_t *)&val);

结果将是 0x0fee1122 而不是 0x00001122; -如果你用隐式强制转换。但它是一个UB

在您的代码中将 int 更改为 short 以使它们大小相同。

另一种解决方案 - 保留 int 和 unsigned 不变,只需重写方法即可;

#define PACKED __attribute__((__packed__))

void MechaQMC5883::read(int* x,int* y,int* z){
    PACKED union {
        short     xs;
        uint8_t   xu[2];
    }xunion;
  Wire.beginTransmission(address);
  Wire.write(0x00);
  Wire.endTransmission();
  Wire.requestFrom(address, 6);
  xunion.xu[0] = Wire.read(); 
  xunion.xu[1] = Wire.read(); 
  *x = (int)xunion.xs;
  xunion.xu[0] = Wire.read(); 
  xunion.xu[1] = Wire.read(); 
  *y = (int)xunion.xs;
  xunion.xu[0] = Wire.read(); 
  xunion.xu[1] = Wire.read(); 
  *z = (int)xunion.xs;
}

问题不是如何转换,而是为什么。图书馆想要 uint16_t*。所以你不应该创建一个 int[N]。相反,创建一个 uint16_t[N],正如库所期望的那样。