I know this is simple basic C stuff, but I can't quite figure it out or find a solution when searching and reading.
I have a method I want to call from a library that wants a const char pointer
someclass::send(const char *data)
And the value I want to send is actually an unsigned integer:
enum messageTypeEnum
{
REGISTER_CLIENT = 0x04,
CLIENT_REGISTERED,
UPDATE_CREDENTIALS,
ADD_BRICK,
GAME_FRAME,
ERROR
};
enum clientTypeEnum
{
GAMEBOARD = 0x01,
BRICK_CONTROLLER,
PLAYER_CONTROLLER,
TOUCH_CONTROLLER
};
uint16_t message = GAMEBOARD;
message <<= 8;
message += REGISTER_CLIENT;
So I want to convert it, but I can't quite figure it out.
I know fundamentally the char pointer is just a pointer to a memory address and that c strings are null terminated, so I should be able to create the pointer, add the enum's underlying bytes to the pointer array, and then add a 0 at the end to terminate it, but I don't know how I would do that exactly.
I tried doing it via casting:
const char *data = (char *)&message;
So here I'm saying (if I'm thinking about it correctly), is:
&message
take the memory address ofmessage
, our uint16- `(char *) interpret it as a pointer for a character string
const char *
store that address in this const pointer
Even typing that out I feel like I'm misunderstanding parts.
This compiles, but it crashes my esp32 and I'm sure it's because I don't have a null terminator at the end, but I'm not sure how to add it (I tried to add it via array index but that failed).
What's the proper way of doing this (I'm sure there's a non-casting way that's probably easier)?
Update
More detail re: PMF and Edgar's comments.
I definitely want to send the binary numbers behind the enums up. I'm building a websocket based interactive project where "controller" websocket clients can drive interactions on "gameboards". Websockets don't have a concept of differentiating between client types (I know socket.io does, but I'm wanting to write it all with regular websockets), so I built a registration system into the server that looks at the first two bytes of an array buffer or blob message to determine the client and message type (it seems overly complicated, but I'm building this to give a talk on binary operations and I'm doing it give functional examples of data parsing).
So yeah, all of that to say I definitely want to send the underlying number values from the enums.
The library I'm using is ArduinoWebsockets and they do have a client method called sendBinary
that does have a signature like the Serial.write
:
Though when I tried this with a non-null terminated c-string my esp32 crashed. That said, I was fumbling around in the code so it may have been something else that caused the crash.
When I follow the method calls down, the library ultimately uses std::string
to pull the data out of the passed in c string and takes in the length (meaning it doesn't need to be null terminated(?)):
So maybe I can use the casting to turn my two byte number into a c string and pass in the length of 16?
message
is actually binary 0x01 0x00 (the esp32 is little endian) and so it does have a terminating 0 as long as the value is smaller than 256.Serial.write()
has the overloadwrite(const uint8_t *buffer, size_t size)
which lets you output an arbitrary array of bytes and doesn't require a NUL terminator (0 is a valid value to output). I have seen this kind of overload in other libraries. Yoursomeclass
may offer something similar for sending binary data. If it doesn't, it's probably not meant to send anything but text, in which case you have to serialize your data as text.sendBinary
method that takes a c string and a length, though I ran into issues when trying to use it. That said, I'm probably understanding it wrong. I'll update my question with more detail.