如何在C++中把结构映射到字符正确的方法
How to map structure to char proper method in C++
在C中,我被用来处理char*,我将一些表示网络数据包的结构映射到char*。然后我只需要分配数据包参数并通过网络发送:
更新-我忘记添加我有一些有效载荷
struct packet {
uint64_t id __attribute__((packed));
uint64_t something __attribute__((packed));
short flags __attribute__((packed));
// here follows payload with variable length
};
...
char *payload = get_payload();
size_t payload_size = get_payload_size();//doesnt matter how
char *data = malloc(sizeof(struct packet)+payload_size);
struct packet *pkt = (struct packet *)data;
pkt->id = 123;
pkt->something = get_something();
pkt->flags = FLAG | FLAG2;
memcpy(data+sizeof(struct packet), payload, payload_size);
send(data, sizeof(struct packet)+payload_size);
现在我想用一些不错的C++特性来实现这一点(如果有更好的方法的话)我在C++中能做的最好的改变是使用new而不是malloc。
char *data = new char[sizeof(struct packet)];//rest is same
好的,这叫做对象序列化。。我发现有几个例子总是使用boost,但我不能使用。。C++中难道没有一种原生的方法来实现这一点吗?
没有理由创建char*
和pkt*
。您创建并发送一个对象,如:
packet pkt; // create automatic object
pkt.id = 123;
pkt.something = get_something();
pktflags = FLAG | FLAG2;
// here we cast the address of pkt to a char* so we can send it
send(reinterpret_cast<char*>(&pkt), sizeof(packet));
编辑:
由于问题已更新为在struct
数据的末尾添加有效载荷,您将不得不使用与在C中相同的方法。当您向上new
指针时,语法将为
char * data = new char[sizeof(packet) + payload_size];
此外,当像在C中那样使用struct
时,C++中不需要struct
关键字。您可以按名称使用它。
我不喜欢您的原始代码依赖于非标准扩展__attribute__((packed))
的方式。由于没有标准的方法要求struct
完全没有填充,因此将结构复制到缓冲区的唯一符合标准的方法是单独复制每个成员。
这启发了我编写一个c++11帮助程序,将可变数量的变量复制到char
数组中。为了帮助使用它,一个助手来计算这些变量的总大小(这里已经完成了)。使用这些助手,您可以轻松地将struct
的成员复制到缓冲区中,而不需要打包struct
。
// variadic sizeof
// mostly same as https://stackoverflow.com/a/12666815/2079303
constexpr std::size_t sizeof_all() {
return 0;
}
template <typename Head, typename... Tail>
constexpr std::size_t sizeof_all(const Head& head, const Tail&... tail) {
return sizeof head + sizeof_all(tail...);
}
// variadic memcpy
void memcpy_all(char*) {}
template <typename Head, typename... Tail>
void memcpy_all(char* out, const Head& head, const Tail&... tail) {
auto offset = sizeof head;
std::memcpy(out, &head, offset);
memcpy_all(out + offset, tail...);
}
// to use
packet p;
std::size_t buffer_size = sizeof_all(p.id, p.something, p.flags) + payload_size;
char* data = new char[buffer_size];
memcpy_all(data, p.id, p.something, p.flags);
现在,您只需要关注endianness。
相关文章:
- 寻找一种更好的方法来表示无符号字符数组
- 打印字符数组地址的正确方法
- 在 std::vector<无符号字符中存储任意数据的方法>
- 在C++事务之间存储大量字符数据的有效方法
- 比较"A"、"C"、"G"'T'字符的最快方法
- 一种将 Dart 中的字节数据转换为 C++ 中的无符号字符*的有效方法?
- C++-将ASCII字符数组中可能的数值转换为字符的最简单方法
- C++ - 创建具有相同字符的特定大小的以 null 结尾的 c 样式字符串的更好方法
- c++14 - 这是在字符串上附加字符的好方法吗?
- 从ostringstream获取最长行的字符数的智能方法
- 常量字符*的模板方法专用化
- 将字符数组设置为彼此相等的方法不起作用
- 字符 - 'pub' 在 std::streambuf::p ubsetbuf() 方法中是什么意思?
- 比较字符* (C/C++) 的最快方法?
- 将大文件读取到字符数组的正确方法
- 使用 fstream 在空格分隔文件中查看下一项(不仅仅是一个字符)的方法
- 将空填充但不以空结尾的固定长度字符数组转换为 std::string 的最佳方法
- isdigit() 和 isalnum() 给出错误,因为输入是一个常量字符并且无法转换。其他可能查看输入是否为数字的方法?
- 我通过迭代加法将二进制数转换为十进制并检查单个字符(请参阅代码)的方法有什么问题?
- 如何使从基类继承的对象访问字符方法,但有自己的结果