如何将 UINT16 转换为两个带符号的字符?

How to convert UINT16 into two signed chars?

我进行此转换是因为从网络接收的数据是 unsigned char[8] 的数组。每两个字节代表一个 UINT16 数字。我想通过套接字发送这些字节,但是,套接字要求字符是 signed(我在小端工作)。

由于无法将 unsigned char 转换为 signed char 我想我可以从两个 unsigned char 形成一个 UINT16 数字,然后将该数字分解为两个 signed char。

我的代码在 UINT16 数字介于 [0,127] 和 [256,65535] 之间的情况下有效,但是当值介于 [128,255] 之间时,第一个字符会爆炸到 ~4294967295 并且 UINT16 现在是表示为 ~65535。任何 explanations/solutions?

uint16_t in = 129;
cout << "input is\t" << in << endl;

char lo = in & 0xFF;
char hi = in >> 8;

printf("%u", lo);
cout << "\n" << endl;
printf("%u", hi);
cout << "\n" << endl;

uint16_t out = lo | uint16_t(hi) << 8;

cout << "out is\t" << out << endl;

通过套接字发送unsigned char[]时出现的错误;如果我使用以下初始化,我可以通过套接字 (winsock) 将它用作 send() 函数的适当参数。工作正常。

char buffer[8]
for (int i= 0; i <8; i++){
 buffer[i] = 0x016; //random data
  }
send(clientSocket, buffer, 8, 0);

但是如果如下初始化缓冲区我得到一个错误:

unsigned char buffer[8]
for (int i=0; i < 8;i++){
 buffer[i] = 0x016; //again random data
 }
 send(clientSocket, buffer,8,0);

错误说明:

int send (SOCKET, const char *, int, int)': cannot convert argument 2 from unsigned char[8] to const char *

[这是针对 C 的回答。OP 尚未阐明他们对 C 与 C++ 答案的需求。]

要使用 send 函数传递名为 bufferunsigned char 数组,该函数具有 const char * 类型的参数,只需将数组转换为所需的输入,如:

send(socket, (const char *) buffer, length, flags);

在 C 中,字符类型用于处理数据的“原始字节”(以及用于对字符进行编码,这是含义和用途的一种不幸的混淆),因此您可以通过这种方式发送任何类型的数据.套接字例程不会根据任何特定类型解释数据;他们将只传输位而不考虑任何符号。您可以在不使用 const 的情况下使用相同的转换来接收数据,只要将数据写入与其最初来自的相同类型的对象即可。

(可能存在发送和接收系统对各种事物使用不同表示的问题,例如 big-endian 存储在一个上而 little-endian 存储在另一个或四个字节上 long 在一个和八个字节上键入另一个或在结构中使用不同的填充和对齐方式。这些是与通过套接字传输原始数据无关的独立问题。)

(,现代的API一般声明这样的参数为void *const void *,传递其他对象指针给它们时不需要强制转换。如果您遇到一些关于此的编译器警告消息,您可能使用了过时的 API。)