1

I have a function UartSend() to send data to network through uart. it takes argument unsigned char and an integer

UartSend(unsigned char *psend_data,int length);

i want to send a structure through this function

#pragma pack(push, 1)
struct packet
{

    int a;
    char b[3];
    ...

}PacketData;

#pragma pack(pop)

How to covert this structure to unsigned char for sending this data through UartSend? thanks..

Shihab
  • 531
  • 1
  • 12
  • 25
  • 1
    did you try simply casting `packet` to `unsigned char*`? It might have alignment problems in your case tho.. – Jimmy Lu Feb 22 '13 at 07:35
  • 5
    Decide on the data format you want. This is called a *protocol*. In your case you'll likely want to send the data as a 32bit or 64bit big-endian integer, followed by exactly three chars. You will "build" this data into a buffer, then send it. The client will receive this, then reconstruct the original struct from the data. Sending a direct-cast can introduce a plethora of alignment and packing issues that honestly, you want to avoid, especially if the client can conceivably be running an a different platformor be of a different memory architecture than your sender. – WhozCraig Feb 22 '13 at 07:41

5 Answers5

5

You can simply cast to unsigned char *, provided you get your size correct:

PacketData pkt;
UartSend((unsigned char *)&pkt, sizeof(pkt));

unsigned char * in this context really just means byte.

Of course, at the other end of the connection, you'll need to incorporate program logic to re-cast to PacketData (or some similar struct).

EDIT: However, note that as @WhozCraig points out in comments, if your destination platform is not identical to your source platform, you need to consider alignment issues (or, alternatively, rely on a GNU extension like __packed__)

Bernhard Barker
  • 54,589
  • 14
  • 104
  • 138
sapi
  • 9,944
  • 8
  • 41
  • 71
0

You can use a union to access your data in the form of your struct, or of an unsigned char array. This way you can avoid aliasing problems that you get with a direct casting.

LtWorf
  • 7,286
  • 6
  • 31
  • 45
0

Structures can have extra bytes in them to make each element aligned. Those extra bytes can vary depending on the compiler/platform being use. As a result, what you want to do may be impossible to do.

I would recommend that you write a function to do the jo. It needs to pull each element out of the structure and send it individually. A second function would be needed to receive the values, and store them back into the function.

Remember that endianism can be an issue as well, and use the network byte ordering functions to make sure that integer values are sent in the standard format. If the systems are different types, floating point values may need some sort of extra conversion step.

Community
  • 1
  • 1
EvilTeach
  • 28,120
  • 21
  • 85
  • 141
0

TipS

  1. byte alignment / pack one. recommend use Natural byte alignment, asure get the best performance. SUN and AIX are 'Natural byte alignment' sensitive.
  2. Byte sequence conversion, normally sender send out with big-endian, receiver convert BYTES to local endian. little (WINDOWS,LINUX) / big (AIX,SUN,HP)
sharingli
  • 138
  • 1
  • 7
0

Your data structure being aligned so that your int falls on word boundries, which for your target might be 32 or 64 bits.

You can reorganize your struct like so so that this won't happen: struct thestruct

{
 int var6;
 unsigned char var1;
 unsigned char var2;
 unsigned char var3[2];
 unsigned char var4;
 unsigned char var5[8];
 unsigned char var7[4];
};
Md. Al Amin Bhuiyan
  • 303
  • 1
  • 3
  • 12