Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在protobuf-c中,可选uint32变量的值是否为0_C_Protocol Buffers - Fatal编程技术网

在protobuf-c中,可选uint32变量的值是否为0

在protobuf-c中,可选uint32变量的值是否为0,c,protocol-buffers,C,Protocol Buffers,案例1-“状态”包含非零值“ 如果状态=非零值 当我使用data_uupack(const data*message,uint8_t*out)函数打包数据时,“out”的长度为100,函数返回100(值100用作示例) 案例2-“状态”包含值0 如果status=0(对于与案例1相同的userid和username值) 当我使用data\uuu pack()函数打包数据时,“out”的长度是99,但函数仍然返回100 如果您注意到上述两种情况,如果变量“status”使用的值为0,则输出缓冲区的

案例1-“状态”包含非零值“

如果状态=非零值 当我使用data_uupack(const data*message,uint8_t*out)函数打包数据时,“out”的长度为100,函数返回100(值100用作示例)

案例2-“状态”包含值0

如果status=0(对于与案例1相同的userid和username值) 当我使用data\uuu pack()函数打包数据时,“out”的长度是99,但函数仍然返回100

如果您注意到上述两种情况,如果变量“status”使用的值为0,则输出缓冲区的长度始终比“status”包含非零值时的长度小1。我已经将has_status变量设置为1,所以这似乎不是问题

这是protobuf bug还是我做错了什么

其他详细信息:我正在使用的Protobuf版本-Protobuf-c-0.15

有关该问题的其他详细信息

Message Data{
   optional uint64 userid = 1;
   repeated string usernames = 2;
   optional uint32 status = 3;
}
我使用data\uu get\u packeted\u size()来获取大小。通过HTTP请求发送到预期的接收者时,我发送的内容长度为'buf_len','buf'用于HTTP正文

Data msg = DATA__INIT;
void* buf = (void*) NULL;
int buf_len = 0;

buf_len = data__get_packed_size(&msg);
buf = (void*) malloc(buf_len+1);

data__pack(&msg, buf);
内容长度:100
内容类型:应用程序/协议
接收器现在继续等待,直到它接收到完整的请求(即100),并且连接最终超时。
在这种情况下,接收器如何知道如何处理这一问题,因为它只等待接收到长度为100的内容?

编码
uint32
需要两个变量,每个变量至少有一个字节长。第一个字节包含编码(“导线”)类型和标签号,如果标签最多为15,则长度为一个字节。第二个变量是整数本身,如果整数最多为127,则长度为一个字节。省略的(“默认”)可选字段根本不占用任何字节;省略的字段不会以任何方式在导线上编码;必须推断他们的缺席

因此,如果省略可选的
uint32
字段,则有线编码将比包含可选字段的相同protobuf至少短两个字节

您没有说明如何计算“out”的长度。唯一正确的方法是在打包
数据
对象之前调用
数据
获取打包大小。但是,我猜您使用的是
strlen(out)
,这不会产生正确的结果
strlen
只能用于字符串;更具体地说,它只能用于
NUL终止的字符串
,因为它在命中
NUL
(0)字节时停止计数,如果没有看到
NUL
字节,则产生未定义的行为。不能对任意二进制数据使用strlen

在protobuf编码中,标签为3且值为0的显式
uint32
将被编码为
0x18 0x00
,而标签为3且值为42的显式
uint32
将被编码为
0x18 0x2A
。如果数据编码之前没有NUL,则
0
编码的第二个字节将终止
strlen
的计数。在某些理想情况下(例如,缓冲区足够长,并且在将消息打包到缓冲区之前清除为所有
NUL
),strlen将
0
的protobuf的长度报告为比
42的protobuf短一个“字符”,因为
0
编码中的
NUL
发生在消息的末尾,导致
strlen
提前一个字节停止计数


这是一种解释,不是一种解决办法。不要在不是以NUL结尾的字符串上使用
strlen

我想当可选值不存在时,它将被视为零。因此,在序列化过程中也可以省略零值。这能解释吗?你是对的。对不起,我没有提到完整的问题。我已经为这个问题添加了更多的细节。你有什么想法吗?@cdemon:你还是不解释为什么你认为
out
只有99个字节?您如何通过HTTP连接将
发送出去
?您使用的API是否仅适用于字符串(即,不需要您指定长度)?当我在接收方看到日志时,我看到它正在等待接收完整的内容长度。我正在使用libevent通过HTTP连接发送。我明白你的意思,你认为如果它只处理字符串,那么发送端会有问题吗?@cdemon:我绝对相信。但你在这里没有提供太多细节。您使用的是
libevent
的简单HTTP服务器吗?另外,该API要求您提供一个
evbuffer
。那么,您是如何创建
evbuffer
?我需要深入研究遗留代码来找出这一点。。谢谢你的支持。如果我发现了什么,我会告诉你的。
Content-Length: 100
Content-Type: application/protobuf

<Body containing the protobuf encoded data - seems to have 99 bytes>