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 开发板相同的结果。
您可以使用 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]
,正如库所期望的那样。
我正在尝试 运行 为 STM32 上的 Arduino 设计的磁力计代码。为 Arduino 编译时,我没有收到任何错误,并且从传感器读取的值已签名。为 STM 编译时出现错误:"no known conversion for argument 1 from 'int*' to 'uint16_t* {aka short unsigned int*}'".
这非常有道理,但从这里到哪里去呢?
目标是获得与普通 Arduino 开发板相同的结果。
您可以使用 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]
,正如库所期望的那样。