将uint8_t*转换为char*以与QIODevice一起使用

Son*_*man 1 c++ io qt buffer pointers

我正在修改Qt音频输出示例,如下所示:

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

如果我的理解是正确的,我应该能够QIODevice通过重写Generator::readData方法来操作方法来调用AudioMixer::ReadData方法并将其uint8_t*使用的方法转换AudioMixer为a char*来使用QIODevice.

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

为了完整起见,方法是:

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

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;
}
Run Code Online (Sandbox Code Playgroud)

Fer*_*yer 8

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

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

char* dst = reinterpret_cast<char*>(/* your uint8_t* expression */);
Run Code Online (Sandbox Code Playgroud)

是否使用reinterpret_cast或C风格的演员表明显有争议.C++的创造者Bjarne Stroustrup 肯定会提倡reinterpret_cast,但其他人不喜欢它,那没关系.

  • `reinterpret_cast`是有原因的,许多C++编码指南清楚地表明你应该更喜欢新式的演员表而不是C式演员表.我不知道你为什么要在这里大惊小怪.是的,它很冗长(Bjarne Stroustoup说这是"丑陋操作的丑陋记谱法"),但是来吧,打字并不多. (5认同)
  • @VladLazarenko——澄清一下:我无意批评你的评论,只是为了回答这个问题。这里是否使用 C 风格还是新风格的强制转换并不是重点。问题的答案是:只需使用类型转换。我不喜欢“reinterpret_cast”,因为它“看起来不像 C”,而是因为它只是 C++ 的实现方式(Stroustrup 甚至表示,如果可以的话,他“想完全禁止 C 风格的强制转换”,请参阅 http:// /www2.research.att.com/~bs/devXinterview.html)。 (2认同)