trying to copy struct members to byte array in c

I am attempting to copy the members of a struct containing a mixture of ints, char's and arrays of chars into a byte array to send to a serial line. So far I have

struct msg_on_send { char descriptor_msg[5]; int address; char space; char cmdmsg[5]; char CR; char LF; }; void switch_output_on() { int member; struct msg_on_send SendMsg_on[sizeof member] = { }; unsigned char buffer [ sizeof SendMsg_on[0] ]; showbytes(buffer, serialize(buffer, SendMsg_on)); } /*************************************************************************** * Function: ArrayBuild * * Purpose: Uses memcopy to transfer the struct members sequentially * * into an array of char * * Arguments: * * Returns: size_t i = a count of the number of bytes in the array * ***************************************************************************/ size_t ArrayBuild(unsigned char *dst, const struct msg_on_send *object) { size_t i = 0; memcpy(&dst[i], &object->descriptor_msg, sizeof object->descriptor_msg); i += sizeof object->descriptor_msg; memcpy(&dst[i], &object->address, sizeof object->address); i += sizeof object->address; memcpy(&dst[i], &object->space, sizeof object->space); i += sizeof object->space; memcpy(&dst[i], &object->cmdmsg, sizeof object->cmdmsg); i += sizeof object->cmdmsg; memcpy(&dst[i], &object->CR, sizeof object->CR); i += sizeof object->CR; memcpy(&dst[i], &object->LF, sizeof object->LF); i += sizeof object->LF; return i; } /*********************************************************************** * Function: USARTWrite * * Purpose: Writes the array data to the USART data register * * Arguments: void *object = struct member * * size_t size = size of array remaining * * Returns: None * ***********************************************************************/ void USARTWrite(const void *object, size_t size) { const unsigned char *byte; for ( byte = object; size--; ++byte ) { printf("%02X", *byte); } putchar('\n'); }

As I obtained this code, I don't fully understand how it works. I can see that the memcpy takes each element of the struct and makes it into a serial stream indexed by the 'i' variable, but I don't know how the USARTWrite function packetises this into a string, or how to load the array with my struct initialisation.

Sorry this post is a bit long, but I'm just starting this programming lark, and trying to get my head around this concept.

Thanks Dave

EDIT:

wow, many good answers quickly - thanks guys.

slaz: That seems logical to me, I hadn't really thought about that approach as I haven't really got my head around pointers yet, but I am beginning to see that they are an essential part of C, so I duly will have a look.

  • This line of code sends the data to my UART, what would I replace the array containing the message contents with? It seems like I am missing a logical step here where I have a variable telling me where my structure starts and how big it is, but no array to send

    USART_SendData(USART1, message_on_contents[array_count]);

Harper Shelby: Thank you for that description, it makes it much clearer in my mind.

rgds

Dave

-------------Problems Reply------------

Hey droseman:
Sorry, I didn't see your comment until just now. The code below compiles on Linux just fine, so I hope it works for you.
printf() is printing in hex, you will get 2 characters for each byte.

#include <stdio.h>

struct msg_on_send
{
char descriptor_msg[5];
int address;
char space;
char cmdmsg[5];
char CR;
char LF;
};

void USARTWrite(const void *object, size_t size)
{
const unsigned char *byte;
for ( byte = object; size--; ++byte )
{
printf("%02X", *byte);
}
putchar('\n');
}

int main (int argc, char**argv)
{
struct msg_on_send myMsg;
unsigned char* ptr= (unsigned char*)&myMsg;

USARTWrite(ptr, sizeof(myMsg));

return 0;
}

I hope this helps.

~
~

You don't have to actually copy the struct into an array of bytes. You could optionally do this:

struct msg_on_send myMessage;

// code to set myMessage to whatever values...

// get a byte pointer that points to the beginning of the struct
uint8_t *bytePtr = (uint8_t*)&myMessage;

// pass that into the write function, and it will write the amount of bytes passed in
USARTWrite(bytePtr, sizeof(myMessage));

The power of pointers! :)

Your struct here is just array of bytes, it contains no pointers that point out of it.

Member-to-member copy is most likely performed to cope with alignment, as (char*) &address will likely be greater than ((char*) &descriptor_msg) + 5.

USARTWrite sends HEX codes of the bytes of your struct to stdout, but discards alignment. Compiling this code with different alignment strategies will lead to different outputs.

Enclose your structure declaration into #pragma pack(push, n) and #pragma pack(pop) to force alignment, and just copy your structure byte-to-byte.

It's fairly straightforward: 1. ArrayBuild takes a pointer to a msg_on_send structure, and for each member in there, uses memcpy to copy the bytes into a char array that was passed in like so -

char byteArray[17]; // This assumes 4-byte ints
// be careful though, the length *must* be long enough, or
// Bad Things will happen
size_t msgSize; // Holds the size of the message built by ArrayBuild,
// passed to USARTWrite
struct msg_on_send myMessage;
// Code to fill up myMessage appropriately

msgSize = ArrayBuild(byteArray, &myMessage); // need the & to pass a pointer as required

USARTWrite(myMessage, msgSize);

USARTWrite is just given a char array and a size - it grabs each char in turn and prints it to the screen as a hex value with printf().

The 'magic' is in the ArrayBuild - memcpy does a literal copy of bytes from source to destination, with no translation. Assuming 4-byte ints, the array built by the function will look like so:

1 1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6
| A | B |C| D |E|F|

A = descriptor_msg (char[5])
B = address (int)
C = space (char)
D = cmdmsg (char[5])
E = CR (char)
F = LF (char)

I'd assume that in the 'real' application, the printf() call would be replaced by a call to a serial port write.

If I want to treat a structure as an array of bytes I typically use a union to combined the structure with a byte array. For example:

typedef union
{
struct
{
char descriptor_msg[5];
int address;
char space;
char cmdmsg[5];
char CR;
char LF;
};
BYTE bytes[];
} msg_on_send;

Category:c# Views:0 Time:2009-01-27

Related post

  • Passing a struct with a byte array inside to a interop-ed method 2011-10-02

    I have a situation where I have to pass a struct to a C method (declared as extern in my C# file). This struct however is quite complicated. I already used successfully the approach with AllocHGlobal, but I would like to understand if is possible to

  • Converting a list of structs to a byte array 2010-11-02

    I have a list of struct, with each struct having two short values and a byte value. I would like to write this to a HEX file just containing the raw data. This HEX value will get loaded onto a microcontroller. Can anyone point me in the right directi

  • Properly copy C# structs with (byte) arrays in them? 2010-08-21

    From what I understand, when assigning a struct variable to another one, the first one is usually copied instead of creating a reference: public struct MYSTRUCT1 { public byte val1; } // (...) public DoSomething() { MYSTRUCT1 test1; test1.val1 = 1; M

  • Copying between byte array and unsigned long 2010-07-06

    What's the best/recommended way to copy data between a byte array and an integer in C? Currently I'm using memcpy, which doesn't feel right to me. A sample of the sort of thing I'm doing is below. struct alpha { unsigned char byte_array[20]; } void f

  • converting between struct and byte array 2010-05-06

    his question is about converting between a struct and a byte array. Many solutions are based around GCHandle.Alloc() and Marshal.StructureToPtr(). The problem is these calls generate garbage. For example, under Windows CE 6 R3 about 400 bytes of garb

  • Access struct members as if they are a single array? 2011-04-02

    I have two structures, with values that should compute a pondered average, like this simplified version: typedef struct { int v_move, v_read, v_suck, v_flush, v_nop, v_call; } values; typedef struct { int qtt_move, qtt_read, qtt_suck, qtd_flush, qtd_

  • Read or convert to Int32 from TWO byte arrays 2010-09-04

    I have the 4 bytes that represent an integer stored in 2 separate byte arrays. I would like to convert these into an Int32 WITHOUT copying to a third byte array and reading that using memorystream. The reason the data is split across two byte arrays

  • Casting a byte array to a managed structure 2011-06-13

    Update: Answers to this question helped me code the open sourced project AlicanC's Modern Warfare 2 Tool on GitHub. You can see how I am reading these packets in MW2Packets.cs and the extensions I've coded to read big endian data in Extensions.cs. I

  • How do you convert a struct into a char array? 2012-04-03

    I am a little bit confused on how to convert a struct to a char[] in C. My CDMA modem doesn't support sending variables - it only understands ASCII characters. I need to do the conversion operation. Let's say that I have an sMSG struct like this: str

  • How to avoid creating new byte arrays for each invocation of a WCF operation method? 2011-04-07

    Is there a way to avoid creating new byte array instances with fixed lengths and calling Array.Copy from the larger byte array Buffer to the newly created reply array called reply? Change the API of the WCF Host!? Use a to-me-unbeknownst method that

  • Convert a struct to a byte[] or void[] in D 2011-11-18

    Is there any quick and easy method of converting a struct to a byte array in D? I'm not really finding anything in the D docs. --------------Solutions------------- void[] arr; MyStruct s; arr = (&s)[0..1]; Dynamic arrays of all types (constness s

  • Copying byte array to various fields in class/struct in C# 2011-08-11

    In the example C# code below, I have a byte array which has been read from a socket. I want to parse the data into the various fields of 'exampleClass' (first 8 bytes into the 64-bit variable 'field1', next 4 bytes into 32-bit variable 'field2', etc.

  • Visual C++ (.NET 4.0) - Serializing/Copy custom struct to Byte-Array for sending via NetworkStream 2011-08-18

    I am working on a TCP-Communication with another person's program. For proper Communication he defined a Header-Struct for the Messages sent via TCP. It is defined something as following: typedef struct { uint16_t number1; uint16_t number2; char name

  • Struct to byte array? 2010-07-19

    How do I convert a structure to a byte array in C#? I have defined a structure like this: public struct CIFSPacket { public uint protocolIdentifier; //The value must be "0xFF+'SMB'". public byte command; public byte errorClass; public byte reserved;

  • Is there a faster/cleaner way to copy structs to an array in C#? 2011-09-17

    I have a float4x4 struct which simply containts 16 floats: struct float4x4 { public float M11; public float M12; public float M13; public float M14; public float M21; public float M22; public float M23; public float M24; public float M31; public floa

  • Structs to Byte Arrays to send over sockets 2009-03-16

    What is the best way to get a byte array from a struct to send over TCP sockets? I'm using .Net (VB or C#). --------------Solutions------------- If you're using C#, you can also marshal it to a native buffer yourself, to have better control over seri

  • List and copying byte arrays? 2012-03-24

    So I'm working with a file format. The file format contains chunks of data... So what I have is an array of List's for the "chunks". Those get added to when I add data to the class via a function. Now, when I save the file, I need to 'insert' a chunk

  • Need loop to copy chunks from byte array 2009-02-24

    I have to process a large byte array that is passed to my function. I need to copy the content from this incoming byte array in smaller "chunks" to an outbound byte array. For every "chunk" of data created in the outbound array, I need to call a web

  • c#: copy variable to byte array 2009-05-25

    How do I copy a double, int, bool or other built-in type to a byte array in C#? I need to do it to use the FileStream.Write() method. --------------Solutions------------- BitConverter.GetBytes() can convert primitive types to byte arrays. Instead of

Copyright (C) dskims.com, All Rights Reserved.

processed in 0.084 (s). 11 q(s)