我正在使用Schembuf在带有套接字的计算机之间更改数据。要传输数据,我使用以下内容:
myProtoMessage::Message m;
string s;
m.SerializeToString(&s);
const char *msg = s.c_str();
// Send msg through socket
然而,我注意到Protobuf无法读取任何非int类型的接收数据(它将其分配给0)。果不其然,如果我不使用套接字,但试图用相同的代码片段返回消息,则会发生相同的情况:
myProtoMessage::Message m;
string s;
m.SerializeToString(&s);
const char *msg = s.c_str();
myProtoMessage::Message m2;
m.ParseFromString(msg); // my data is lost
我还指出:
myProtoMessage::Message m;
string s;
m.SerializeToString(&s);
const char *msg = s.c_str();
string(msg) == s; // 0
// Let's try it again
string s2;
int size_msg = sizeof(msg) / sizeof(char);
s2.assign(msg, size_msg);
s2 == s; // still 0
myProtoMessage::Message m2;
m.ParseFromString(s2); // the data is lost
那么,为什么我不能正确地将数据转换回字符串呢?如果这是一个参考问题,为什么protobuf不能读取字符数组数据或从字符数组转换的字符串数据?任何帮助都将不胜感激。
我的代码的一个更好的例子:原型消息(message.proto)
syntax = 'proto3';
package message;
message Message1{
uint64 time_us = 1;
uint32 id = 2;
}
message Message2{
uint64 id= 1;
double l1= 2;
double l2 = 3;
float l3 = 4;
enum MyEnum {
IDLE = 0;
}
MyEnum myEnum = 8;
}
message CompleteMessage{
Message1 message1 = 1;
Message2 message2 = 2;
}
我的代码:
#include <iostream>
#include "message.pb.h"
#include "boost/asio.hpp"
using namespace boost::asio;
using namespace std;
// Send data through socker
void send_message(const char* msg, int msg_size, const char* IP, int port)
{
io_service io_service;
ip::udp::socket socket(io_service);
ip::udp::endpoint remote_endpoint;
socket.open(ip::udp::v4());
remote_endpoint = ip::udp::endpoint(ip::address::from_string(IP), port);
boost::system::error_code err;
socket.send_to(buffer(msg, msg_size), remote_endpoint, 0, err);
socket.close();
}
// Fill message data
void fill_m1_data(message::Message1* msg, uint64_t time_us, uint32_t id)
{
msg->set_id(id);
msg->set_time_us(time_us);
}
// Fill message data
void fill_m2_data(message::Message2* msg, uint64_t loaded_mission_id,
double latitude, double longitude, float altitude,
message::Message2::MyEnum state)
{
msg->set_id(loaded_mission_id);
msg->set_l1(latitude);
msg->set_l2(longitude);
msg->set_l3(altitude);
msg->set_myEnum (state);
}
int main(int argc, char const *argv[])
{
message::CompleteMessage m;
fill_m1_data(m.mutable_message1(), 1, 1);
fill_m2_data(m.mutable_message2(), 1, 22.0, 42.0, 10.f,
message::Message2::MyEnum::MyEnum_IDLE);
// Convert protobuf data to string
string s;
m.SerializeToString(&s);
const char *msg = s.c_str();
// Check the data, everything is fine
cout << "message 2" << endl;
cout << m.message2().id() << endl;
cout << m.message2().l1() << endl;
cout << m.message2().l2() << endl;
cout << m.message2().l3() << endl;
cout << m.message2().myEnum() << endl;
cout << "message 1" << endl;
cout << m.message1().id() << endl;
cout << m.message1().time_us() << endl;
// Get back the data
message::CompleteMessage m2;
m2.ParseFromString(msg); // get data back
// converting msg back to string by the methods above yields the same results
cout << "message 2" << endl;
cout << m.message2().id() << endl;
cout << m.message2().l1() << endl; // 0, should be 22.0
cout << m.message2().l2() << endl; // 0, should be 42.0
cout << m.message2().l3() << endl; // 0, should be 10.0f
cout << m.message2().myEnum() << endl;
cout << "message 1" << endl;
cout << m.message1().id() << endl;
cout << m.message1().time_us() << endl;
// Send the message
send_message(msg, s.length() - 1, "192.168.0.0", 9000);
return 0;
}
原型留档:https://developers.google.com/protocol-buffers/docs/cpptutorial
通过套接字发送和接收数据时,以下代码起作用:
// send
string s;
msg.SerializeToString(&s);
void *buffer = malloc(s.size());
msg.SerializeToArray(buffer, s.size());
send(fd, buffer, s.size(), 0);
free(buffer);
// receive
numbytes = recv(connectfd, buf, MAXDATASIZE, 0);
buf[numbytes] = '\0';
// Receive msg from clients
message::CompleteMessage m;
m.ParsePartialFromArray(buf, sizeof(buf) / sizeof(char)); // sizeof(buf) / sizeof(char) can be changed to numbytes
虽然不是最干净的,但却很管用。不过,关于字符串和字符数组的问题仍然存在。
从protobuf消息序列化的字符串是二进制字符串。不能用单个二进制字符指针构造std::string
。相反,您还应该指定二进制字符串的大小。
myProtoMessage::Message m;
string s;
m.SerializeToString(&s);
const char *msg = s.c_str();
myProtoMessage::Message m2;
// in this case, msg will be converted to std::string,
// and will be truncated when it meets the first '\0'.
// That's why your data is lost
// m.ParseFromString(msg); // my data is lost
// Instead, you should call `ParseFromArray` to specify the size of the string buffer.
m.ParseFromArray(msg, s.size());
// Or construct a std::string manually.
m.ParseFromString(std::string(msg, s.size()));
myProtoMessage::Message m;
string s;
m.SerializeToString(&s);
const char *msg = s.c_str();
// Send msg through socket
// When you send msg, also specify the size of the message:
// send(sock, msg, s.size(), flags);
试图对这个问题中的各个数字求和。然而,当涉及负数时,函数就会分崩离析。这是因为当您使用toString()时,会将负号转换为NewStr中的值。例如,在本例中,newstr[0]==='-'。不管怎么说都是为了解决这个问题?最好使用Number()函数
我有一个购物车php页面,在那里我显示客户端产品。在同一页中,我有一个表单,可以将客户的个人详细信息(如姓名、姓氏等)以及产品信息(如产品名称、数量等)直接发送到我的电子邮件地址。 现在,问题是,当我发送表单时,在我的电子邮件地址上,我收到了所有的信息,但没有产品细节,例如在订单电子邮件中的产品名称字段,我有ARRAY。 我看到将数组转换为字符串时出现问题,但我不知道如何转换,我尝试了几个示例,但
问题内容: 是否可以将字符串转换为字节数组,然后在Java或Android中将其转换回原始字符串? 我的目标是将一些字符串发送到微控制器(Arduino)并将其存储到EEPROM(仅1 KB)中。我尝试使用MD5哈希,但它似乎只是一种单向加密。我该怎么办? 问题答案: 我建议使用字符串的成员,但 使用显式编码 : 通过使用一种显式编码(以及一种支持所有Unicode的编码),您可以避免仅调用等问题
为什么toString方法返回jibberish?
问题内容: 如何将经典字符串转换为f字符串? 输出: 所需的输出: 问题答案: f字符串是 语法 ,而不是对象类型。您不能将任意字符串转换为该语法,该语法会创建一个字符串对象,而不是相反。 我假设您想用作模板,因此只需在对象上使用方法: 如果要提供可配置的模板服务,请创建一个包含所有可以插值的字段的名称空间字典,并与调用语法一起使用以应用名称空间: 然后,用户可以在字段中的名称空间中使用任何键(或
问题内容: 我想将a转换为Character类的对象数组,但无法执行转换。我知道我可以使用该方法将String转换为原始数据类型类型为“ char”的数组,但这无助于将String转换为Character类型的对象数组。 我将如何去做? 问题答案: 用这个: