将 uint8_t* 更改为 char*?
Posted
技术标签:
【中文标题】将 uint8_t* 更改为 char*?【英文标题】:Change uint8_t* to char*? 【发布时间】:2019-05-15 14:31:44 【问题描述】:我有一个请求char*
的 API,这是我的 API 函数:
CANMessage(unsigned _id, const char* _data, char _len = 8)
更多信息在这里:https://os.mbed.com/docs/mbed-os/v5.11/mbed-os-api-doxy/classmbed_1_1_c_a_n_message.html
我想从另一个函数中调用这个函数,但我对const char*
和强制转换感到困惑。我想从函数foo()
调用这个函数,像这样:
void foo(unsigned int id, /*???*/ data, char len)
CANMessage(id, data, len)
所以我需要将 id、data 和 len 传递给函数 foo。我的问题是进来的data
是uint8_t
类型。我得到了一个uint8_t
的向量,其中第一个元素的地址是我需要传递的:
vector<uint8_t> dta;
我试图将其传递为&dta[0]
:foo(idNo, &dta[0], length)
使用 foo 函数如下:
void foo(unsigned int id, uint8_t* data, char len)
CANMessage(id, (char*)data, len)
但我得到“std::uint8_t * 类型的参数与 char* 类型的参数不兼容
当调用它的函数foo
接受uint8_t*
时,我如何将它作为const char*
传递?
请注意,我无法更改类型,dta 必须保留vector<uint8_t>
。
【问题讨论】:
请注意,char
可能是 signed
或 unsigned
(取决于您的实现),并且在这两种情况下,char
都是与 signed char
和 unsigned char
不同的类型。
一般来说,您应该将任何 C 风格的转换视为您做错了什么的危险信号。
至于您的问题,能否请您复制粘贴 full 和 *complete 错误输出,包括任何可能的信息说明。
请提供MCVE。一般来说,转换为const char *
应该没有问题。
我无法重现您的示例的问题(缺少部分以使其完整):coliru.stacked-crooked.com/a/1b54a11a5b0a341f
【参考方案1】:
std::uint8_t
等于 unsigned char
。
这与普通字符或签名字符不同,但它们都是 8 位的,因此在技术上可以进行转换。
通常需要“缓冲区”的许多函数在其定义中使用char*
而不是正确的unsigned char*
。因此,铸造很可能是无害的。
如果函数实际上需要字符而不是缓冲区,那么您就会遇到问题,因为类型不同,您是否会遇到问题是不确定的。
【讨论】:
"std::uint8_t
等于 unsigned char
" 这是必需的吗?它可以合法地成为扩展整数类型吗?
@FrançoisAndrieux 如果std::uint8_t
存在,那么unsigned char
必须是无符号的8 位类型。如果CHAR_BIT > 8
则 uint8_t 不能存在
@phuclv 我同意如果std::uint8_t
被定义,unsigned char
必然是它的兼容候选者。我想知道是否需要std::uint8_t
实际上是unsigned char
。我不明白为什么实现会这样做,即使提供了另一个 unsigned
8 位整数类型。您不妨将其定义为unsigned char
,但我不确定它是否必须。
std::uint8_t
是定义类型,unsigned char
是内置类型。定义的类型必须以某种方式在内置类型的帮助下定义。如果不使用unsigned char
,还能用什么?
@MichaelChourdakis 它可能是extended integer type,它们有资格作为基本整数类型。例如,由于我无法想象的原因,我的编译器可能有一个 __unsigned_byte
类型或其他东西。编辑:还有 char8_t
自 C++20 以来与 unsigned char
具有相同的大小、符号和对齐方式。【参考方案2】:
由于您处于std::uint8_t
可用的环境中,char
类型必须最多为 8 位,但为了确保您不在具有 7 位字符的机器上,请添加 static_assert
。
reinterpret_cast uint8_t*
到 const char*
和 static_cast 向量的大小 (size_t
) 到 char
。
void foo(unsigned _id, const std::vector<uint8_t>& dta)
static_assert(CHAR_BIT == 8, "Strange char");
CANMessage(
_id,
reinterpret_cast<const char*>(dta.data()),
static_cast<char>(dta.size())
);
【讨论】:
C 和 C++ 都要求char
的所有风格至少为 8 位。这来自<limits.h>
中CHAR_BIT
的定义,它通过<climits>
进入C++。
@PeteBecker 我不知道char
s 自己有少于 8 位的任何系统,但是这里有很多关于 SO 提到 6 位和 7 位字符历史机器的其他讨论。不过,人们可能会忽略这些 Today :-) ... 但即使 uint8_t
和 char
都有 8 位 - 正如 François Andrieux 指出的那样,它们不一定是位兼容的。以上是关于将 uint8_t* 更改为 char*?的主要内容,如果未能解决你的问题,请参考以下文章
将 unsigned char 数组转换为 uint8_t 数组?
错误:从“uint8_t* aka unsigned char*”转换为“unsigned int”会丢失精度 [-fpermissive]