+-
c – 使用std :: string作为通用的uint8_t缓冲区
我正在浏览Chromium的源代码,以研究他们如何实现将原始麦克风输入流编码/记录到特定格式的MediaRecorder API.

我遇到了interesting codes from their source.总之:

bool DoEncode(float* data_in, std::string* data_out) {
    ...
    data_out->resize(MAX_DATA_BTYES_OR_SOMETHING);
    opus_encode_float(
        data_in,
        reinterpret_cast<uint8_t*>(base::data(*data_out))
    );
    ...
}

所以DoEncode(C方法)接受一个float数组并将其转换为编码字节流,实际操作在opus_encode_float()(这是一个纯C函数)中完成.

有趣的是,Google Chromium团队使用std :: string作为字节数组而不是std :: vector< uint_8>他们甚至手动转换为uint8_t缓冲区.

为什么来自Google Chromium团队的人会这样做,并且有一种情况是使用std :: string对于通用字节缓冲区比使用其他如std :: vector< uint8_t>?更有用.

最佳答案
Chromium编码风格(见下文)禁止使用无符号整数类型,没有充分理由.外部API不是这样的原因.有符号和无符号字符的大小为1,所以为什么不呢.

我查看了opus编码器API,似乎早期版本使用了signed char:

[out]   data    char*: Output payload (at least max_data_bytes long)

虽然API现在使用无符号字符,但描述仍然引用了signed char.所以std :: string for chars对于早期的API来说更方便,而且Chromium团队在API更新后没有更改已经使用过的容器,他们在一行中使用了cast而不是更新了其他几十行.

整数类型

您不应该使用无符号整数类型,例如uint32_t,除非有一个有效的原因,例如表示位模式而不是数字,或者您需要定义溢出模2 ^ N.特别是,不要使用无符号类型来表示数字永远不会是负数.相反,请使用断言.

如果您的代码是返回大小的容器,请确保使用适合容器的任何可能用途的类型.如有疑问,请使用较大的类型而不是较小的类型.

转换整数类型时要小心.整数转换和促销可能导致未定义的行为,从而导致安全漏洞和其他问题.

在无符号整数上

无符号整数有利于表示位域和模运算.由于历史事故,C标准也使用无符号整数来表示容器的大小 – 标准组织的许多成员认为这是一个错误,但在这一点上实际上无法修复.无符号算术不对一个简单整数的行为进行建模,而是通过标准来定义模块化算法(包含溢出/下溢),这意味着编译器无法诊断出一大类错误.在其他情况下,定义的行为会阻碍优化.

也就是说,混合整数类型的签名是造成同样大类问题的原因.我们可以提供的最佳建议:尝试使用迭代器和容器而不是指针和大小,尽量不要混合签名,并尽量避免使用无符号类型(除了表示位域或模运算).不要仅使用无符号类型断言变量是非负的.

点击查看更多相关文章

转载注明原文:c – 使用std :: string作为通用的uint8_t缓冲区 - 乐贴网