在 C++ 中从 size_t 转换/转换为 uint8_t?

发布于 2024-12-10 19:20:01 字数 921 浏览 0 评论 0原文

我正在尝试编写一些代码,使用 boost::asio 的套接字将消息从一端(客户端)发送到另一端(服务器)。

我现在的具体目标是在发送的每条消息前面添加一个 1 字节无符号整数 (uint8_t),告诉接收者消息的其余部分有多少字节长。

请注意,我将大小存储和传输为 uint8_t 而不是 size_t 的原因是因为我想确保它在两台机器上都恰好是 1 个字节。谷歌搜索表明,机器 A 和机器 B 上的 size_t 大小可能不同,这可能会把事情搞砸。

所以我在这里计算消息的长度。该消息仅由两部分组成:一个 uint16_t,后跟一个变量“data”,它是一个 (void*) 转换的内存块,将用于不同的目的(目标机器有解释该数据的方法,但我不会'在此不进行讨论)。

uint8_t sizeOfMessage = sizeof(uint16_t) + sizeof(data);

在此示例中,sizeof(data) == 4,因此 sizeOfMessage 应等于 6(因为 uint16_t 是 2 字节整数)。但是,如果我 std::cout << sizeOfMessage,显示的不是6,而是一个特殊字符:黑桃(如扑克牌中的那样)。在VS2010的调试器中查看数据,它显示为 6 '-' 。但是,如果我将 sizeOfMessage 定义为 size_t 并将其打印出来,则一切都很好(但是当然,我无法通过网络发送它,因为不能保证 size_t 的字节大小从一台机器到另一台机器)。

我认为这意味着在算术之后将 size_t 转换为 uint8_t 的方式出了问题。 sizeof 返回一个 size_t,所以我的代码所做的就是添加两个 size_t,然后将其转换为 uint8_t。

我的结论是否正确,即该值未正确转换?如果是这样,我该如何解决这个问题?

提前致谢。

I'm trying to write some code that uses boost::asio's sockets to send a message from one end (the client) to another (the server).

My particular goal right now is to prepend every message being sent with a 1-byte unsigned integer (uint8_t) telling the receiver how many bytes long the rest of the message is.

Note that the reason I'm storing and transferring the size as a uint8_t instead of a size_t is because I want to ensure that it will be exactly 1 byte on both machines. A little googling has indicated that size_t can be of a different size on machine A versus machine B, which could mess things up.

So here I'm calculating the length of the message. The message consists of just two parts: a uint16_t, followed by a variable "data" which is a (void*)-cast chunk of memory that will serve varying purposes (the target machine has ways of interpreting that data, but I won't get into that here).

uint8_t sizeOfMessage = sizeof(uint16_t) + sizeof(data);

In this example, sizeof(data) == 4, so sizeOfMessage should equal 6 (since uint16_t is a 2-byte integer). However, if I std::cout << sizeOfMessage, what's displayed is not 6, but a special character: a spade (as in the suit of cards). Looking at the data in VS2010's debugger, it shows up as 6 '-' . However, if I define sizeOfMessage as a size_t and print that out, everything is fine (but of course, I can't send that over the network because the size in bytes of a size_t is not guaranteed from one machine to the next).

I take this to mean something is going wrong in how size_t is being cast into a uint8_t after the arithmetic. sizeof returns a size_t, so what my code is doing is adding two size_t's and then casting that into a uint8_t.

Am I correct in my conclusion that the value is not being cast correctly? If so, how can I solve this?

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

木森分化 2024-12-17 19:20:01

分配给您的小 (uint8_t) 变量的值不是显示为“6”的可打印 ASCII 字符代码。相反,它是一个二进制值,相当于在源代码中编码“\006”。如果您的数据传输协议确实适用于二进制代码字节,那么您可能就可以开始了。接收程序在其读入一个字节(char)的(uint8_t)实例中得到什么?当然,使用 (uint8_t) 将消息总长度限制为 0 到 255(但您知道这一点)。

The value being assigned to your little (uint8_t) variable is not a printable ASCII character code that would display like '6'. Instead, it is a binary value, which is equivalent to coding '\006' in your source code. If your data transfer protocol does work with binary code bytes, you're probably good to go. What does the receiving program get in its instance of (uint8_t) which it reads one byte (char) into? And of course using (uint8_t) limits your total message length to 0 through 255 (but you knew that).

﹏半生如梦愿梦如真 2024-12-17 19:20:01

uint8_t 通常是 char 类型的 typedef,并且它们被重载以用于格式化输出以打印为字符,而不是数字。不幸的是,这是 C++ 格式 I/O 的丑陋方面之一,因为您必须转换为整数才能打印:

char c;
unsigned char u;

std::cout << (unsigned int)(unsigned char)(c) << std::endl
          << (unsigned int)(u) << std::endl;

uint8_t is usually a typedef for a char type, and those are overloaded for formatted output to print as characters, not as numbers. Unfortunately this is one of the uglier sides of C++ formatted I/O, as you'll have to convert to integer to print:

char c;
unsigned char u;

std::cout << (unsigned int)(unsigned char)(c) << std::endl
          << (unsigned int)(u) << std::endl;
虫児飞 2024-12-17 19:20:01

uint8_t 在您的系统中是一个unsigned char,因此输出它会将其写为字符而不是整数,即值为 6 的字符。

您的转换没​​有任何问题。

uint8_t is an unsigned char in your system, so outputing it writes it as a character instead of an integral, the character whose value is 6.

There is nothing wrong with your cast.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文