TransWikia.com

How to convert UINT16 into two signed chars?

Stack Overflow Asked by the big pescado on February 22, 2021

I’m doing this conversion is because from a network where the data being received is an array of unsigned char[8]. Every two bytes represent a UINT16 number. I want to send these bytes through a socket however, sockets require the chars to be signed (I’m working in little-endian).

Since it is impossible to convert a unsigned char to signed char I thought I could form a UINT16 number from the two unsigned chars and then decompose the number into two signed chars.

The code I have works in situations when the UINT16 number is between [0,127] and [256,65535], but when the value is between [128,255] the first char blows up to ~4294967295 and the UINT16 is now represented as ~65535. Any explanations/solutions?

uint16_t in = 129;
cout << "input ist" << 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 ist" << out << endl;

The error I get when I send unsigned char[] through the socket; if I use the following initialization I can use it as an appropriate argument for the send() function through the socket (winsock). Works just fine.

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

But if initialize the buffer as following I get an error:

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

With the error stating:

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

One Answer

[This is answered for C. OP has yet to clarify their needs for C versus C++ answers.]

To pass an array of unsigned char named buffer using the send function, which has an parameter of type of const char *, simply cast the array to the required type, as with:

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

In C, character types are used to deal with “raw bytes” of data (as well as being used to encode characters, an unfortunate conflation of meanings and uses), so you can send any type of data this way. The socket routines will not interpret the data according to any particular type; they will just transmit the bits without regard to any signedness. You can use the same cast without const for receiving data, as long as the data is written to the same type of object that it originally came from.

(There can be issues where the sending and receiving systems use different representations for various things, such as big-endian storage on one and little-endian storage on another or four bytes for long type on one and eight bytes on another or different padding and alignment in structures. These are separate issues unrelated to the transmission of raw data via sockets.)

(As noted by Kaz, modern APIs generally declare such parameters to be void * or const void *, and no cast is necessary when passing other object pointers to them. If you encountered some compiler warning message about this, you may be using an outdated API.)

Correct answer by Eric Postpischil on February 22, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP