将 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。我的问题是进来的datauint8_t 类型。我得到了一个uint8_t 的向量,其中第一个元素的地址是我需要传递的:

vector<uint8_t> dta;

我试图将其传递为&amp;dta[0]foo(idNo, &amp;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&lt;uint8_t&gt;

【问题讨论】:

请注意,char 可能是 signedunsigned(取决于您的实现),并且在这两种情况下,char 都是与 signed charunsigned 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 &gt; 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 位。这来自&lt;limits.h&gt;CHAR_BIT 的定义,它通过&lt;climits&gt; 进入C++。 @PeteBecker 我不知道chars 自己有少于 8 位的任何系统,但是这里有很多关于 SO 提到 6 位和 7 位字符历史机器的其他讨论。不过,人们可能会忽略这些 Today :-) ... 但即使 uint8_tchar 都有 8 位 - 正如 François Andrieux 指出的那样,它们不一定是位兼容的。

以上是关于将 uint8_t* 更改为 char*?的主要内容,如果未能解决你的问题,请参考以下文章

将 unsigned char 数组转换为 uint8_t 数组?

如何将字符数组转换为 uint8_t

uint8_t 和 unsigned char 链接错误

c char 数组到 uint8_t 数组

错误:从“uint8_t* aka unsigned char*”转换为“unsigned int”会丢失精度 [-fpermissive]

用元素加载 std::queue<uint8_t*> 的更有效方法?