【问题标题】:Converting vector<char> that contains cbor data to const char *将包含 cbor 数据的 vector<char> 转换为 const char *
【发布时间】:2020-11-11 13:50:54
【问题描述】:

我有一个包含 cbor 字节的 uint8_t 向量,我必须将字节转换或复制到 const char * 以在 POSIX 消息队列中使用。我尝试了以下方法

vector<uint8_t> cbor_data{/*has some data*/};
const char *data = (const char *)(cbor_data.data());

vector<uint8_t> cbor_data{/*has some data*/};
char* data = new char[cbor_data.size() + 1];
memcpy(data, cbor_data.data(), cbor_data.size());
data[cbor_data.size()] = '\0';

但只有一部分数据被强制转换或复制。这两种方法似乎都失败了。我有几个字节的值为 0。例如,这就是我在向量中的内容:

a1,69,72,65,6d,69,6e,64,65,72,73,88,a5,66,63,6f,6e,66,69,67,a5,67,65,6e,61,62,6c,65,64,f4,72,72,65,6d,69,
6e,64,65,72,45,78,70,69,72,79,54,79,70,65,72,73,79,73,74,65,6d,43,61,6c,65,6e,64,61,72,54,69,6d,65,6c,72,
65,6d,69,6e,64,65,72,54,69,6d,65,00,66,76,69,65,77,65,64,f4,6b,77,72,69,74,65,41,63,63,65,73,73,66,72,65,
6d,6f,74,65,62,69,64,00,69,70,75,62,6c,69,73,68,65,72,a2,6c,64,6f,4e,6f,74,50,65,72,73,69,73,74,f5,6d,70

这是我打印数据时剩下的内容:

a1,69,72,65,6d,69,6e,64,65,72,73,88,a5,66,63,6f,6e,66,69,67,a5,67,65,6e,61,62,6c,65,64,f4,72,72,65,6d,69,
6e,64,65,72,45,78,70,69,72,79,54,79,70,65,72,73,79,73,74,65,6d,43,61,6c,65,6e,64,61,72,54,69,6d,65,6c,72,
65,6d,69,6e,64,65,72,54,69,6d,65,00

00 之后的一切似乎都丢失了。它不仅仅是在打印数据时。 strlen(data) 和 cbor_data.size() 不匹配。还有其他方法可以解决这个问题吗?还是将 char/uint8_t 向量传递给 posix 消息队列的更好方法?

【问题讨论】:

  • 由于 char 00 是字符串终止符,打印 char* 将停止。在那个字符之后,其余的可能就在那里。 ;) 也许您可以替换 0 字节或有多个 char* 字符串。
  • 是的,您是直接将 00 打印为 char 还是先将字符 '0' 的值添加到每个数字,然后再打印出来,这样您的打印语句就不会将 00 解释为空终止符/结束打印在那里?打印似乎与其他数字一起工作得很好,所以很难说问题出在哪里。您是否尝试过调试器,或者您能否更具体地了解如何打印数据?如果您使用的是 std::cout 流,则问题不在打印中,但如果不是,则可能是。
  • 如果您的字符串包含嵌入的 nul 字符,您需要同时传递一个大小,因为它的真实大小无法自动确定。 (这是 std::string 相对于原始字符数组的优势之一——另一个优势是自动内存管理。)请注意,例如,strlen("a\0b") == 1 即使字符串显然是 3 个字符长。
  • @JoopEggen 你是对的!我依靠 strlen() 和 cbor_data.size() 来匹配。但 strlen() 也会在空终止符处返回。但是我的问题在接收端仍然存在。我收到一个 cont char *(可能包含空字符)和最大消息大小,它比发送的实际数据大得多。
  • 您的实际输入是什么? vector&lt;uint8_t&gt; 还是 cont char *?如果输入是给定长度的cont char *,您仍然可以将它们放在缓冲区中。但是你的问题闻起来像XY problem

标签: c++ pointers vector char message-queue


【解决方案1】:

问题:

将 char/uint8_t 向量传递给 posix 消息队列的更好方法?

实际问题在您的评论中,

我可以传递实际大小,但在接收端缓冲区的大小远大于实际消息长度。

因为它是一个原始指针,所以mq_receive 的大小必须比 msg 的实际大小更大。

了解recv大小的实际数据长度的方法是定义你自己的消息协议。

例如:前4个字节表示数据长度,后4个字节表示源进程标签,其余数据为cbor数据。

一个简单的图表:

================================================================
| Data Legnth | Process ID or insert what you want | cbor data |
================================================================

【讨论】:

    【解决方案2】:

    如前所述,char 00 终止 C 风格的字符串。

    如果接收者期望CBOR二进制数据,它应该处理一个 00 字符。

    00 = 3 位 000 表示无符号整数 + 5 位有效负载 0-23 或字节长度指示符,在这种情况下为无符号整数有效负载 0。无符号整数 0 也可以表示更长,但它总是以至少结尾一个 0 字节。

    您可以尝试使用 0 的“负”整数:3 位 001 + 有效负载 00000。

    所以尝试用 0x40 代替 00。没有 CBOR 经验,所以不确定。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多