【问题标题】:Converting uint8_t* to char* for use with QIODevice将 uint8_t* 转换为 char* 以用于 QIODevice
【发布时间】:2012-04-24 13:12:26
【问题描述】:

我正在修改Qt Audio Output example如下:

  • 我可以访问第三方的音频混音器 API。
  • 从这个混音器读取数据的方法是void AudioMixer::ReadData(uint8_t *stream, uint32_t len);
  • 在示例中我更改为输出此数据的函数是qint64 Generator::readData(char *data, qint64 len)

如果我的理解是正确的,我应该可以通过覆盖Generator::readData方法调用AudioMixer::ReadData方法并将AudioMixer使用的uint8_t*转换为推送模式来操作QIODevice char*QIODevice 一起使用。

我认为这是可能的吗?如果是这样,有人可以建议如何进行演员表吗?如果没有,您能否解释一下如何使用QIODevice 输出uint8_t*

为了完整起见,方法是:

void AudioMixer::ReadData(uint8_t *stream, uint32_t len)
{   
    if(buffer.GetMaximumReadSize() < len)
    {
        memset(stream, 0, len);
    }
    else
    {
        buffer.Read(stream, len);
    }
}

qint64 Generator::readData(char *data, qint64 len)
{
    qint64 total = 0;
    while (len - total > 0) {
        const qint64 chunk = qMin((m_buffer.size() - m_pos), len - total);
        memcpy(data + total, m_buffer.constData() + m_pos, chunk);
        m_pos = (m_pos + chunk) % m_buffer.size();
        total += chunk;

        // Need to call AudioMixer::readData in here
    }
    return total;
}

【问题讨论】:

  • uint8_t *a; char *b = (char *)a;
  • 真的就这么简单吗?是否因为 char 本质上已签名而没有潜在问题?
  • 只有当您要进行位移操作时,签名(没有更好的词)才应该是相关的。如果右移无符号变量总是用 0 填充,有符号变量根据值用 1 或 0 填充。

标签: c++ qt pointers io buffer


【解决方案1】:

在 C++ 中没有表示“字节”的本机类型,只有 char 保证恰好容纳一个字节。对于表示原始二进制数据的字节类型是否应该签名存在不同的意见,因此有些使用unsigned charuint8_t)而其他使用纯char。最后,这并不重要,因为您通常不会对二进制数据执行算术运算,而只是读取和解释它。

因此,您可以只使用类型转换在不同的二进制数据表示之间进行转换。由于这是 C++,您应该使用 reinterpret_cast(支持 C 风格的强制转换):

char* dst = reinterpret_cast<char*>(/* your uint8_t* expression */);

是否使用reinterpret_cast 或C 风格的演员表显然是有争议的。 C++ 的创造者 Bjarne Stroustrup 会 certainly advocate for reinterpret_cast,但其他人不喜欢它,没关系。

【讨论】:

  • 无论是否需要,都停止推送 reinterpret_cast。 reinterp.... 需要大量输入,在这种情况下,它完全等同于老式的 C 类型转换。在某些情况下,它在运行时确实很重要(即 vtable 偏移量)或有助于类型安全(无意的错误类型转换)。但实际上,您必须理解它,而不是有一个愚蠢的规则说 - 仅仅因为它看起来更像 C 就输入更多。
  • “应该使用”不,你不应该。您“应该”使用最简单的正确解决方案。在这种情况下,这是 C 风格的转换。
  • reinterpret_cast 的存在是有原因的,并且许多 C++ 编码指南明确指出,您应该更喜欢新风格的转换而不是 C 风格的转换。我不知道你为什么在这里大惊小怪。是的,它很长(Bjarne Stroustoup 说它是“丑陋操作的丑陋符号”),但是拜托,打字并不多。
  • @VladLazarenko -- 明确一点:我无意批评您的评论,只是为了回答这个问题。在这里是使用 C 风格还是新风格的演员表不是重点。问题的答案是:只需使用类型转换。我不赞成 reinterpret_cast,因为它“看起来不像 C”,而是因为它只是 C++ 的方式(Stroustrup 甚至说如果可以的话,他会“想完全禁止 C 风格的演员表”,请参阅 www2.research.att.com/~bs/devXinterview.html )。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-23
  • 2019-10-14
  • 2021-07-11
  • 2019-01-09
  • 2013-09-01
  • 2019-11-21
  • 1970-01-01
相关资源
最近更新 更多