0

For an USB and serial application, I implement a protocol, and in C/C++ it can be neatly done by structure casting into the buffer, which it makes it handy to encode / decode from data to a byte array, which can then be forwarded to an USB or Serial port.

The other end is communicating with a micro controller. An advantage of this, is that the structure and packing / unpacking mechanism can be a shared code between the host application and the micro-controller application.

Here is an example of a data packing into a char buffer.

Edit: Note that the structure is packed, which means there is no padding between the types.

#pragma pack(push,2)
typedef struct 
{
    uint32_t address ;
    uint32_t len;
    uint16_t crc;
} FlashData;
#pragma pack(pop)


unsigned char buf[size + sizeof(FlashData)] __attribute__((aligned));

FlashData *flashData = (FlashData*) &buf[0];
flashData->address = startAddr;
flashData->len = size;
[...]

Is there a simple way to reproduce this sort of casting in C#?

Many years ago I did similar communication in C# but I remember I had to serialize data an manually unpack, which was a pain.

There are some C# example of copying C# data structure to byte arrays, but since every object and type are inherited in C#, I am not sure that would be a good solution.

Another way could be to have a solution with both C++ and C# project, C++ taking care of low level communication and C# higher level and UI management, link by DLL.


EDIT

Answer was actually given by elgonzo on the comments.

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    private struct Packet
    {
        public byte header;
        public byte cmd;
        public ushort address;
        public ushort len;
        public ushort crc;
    }

and the GetByte method

Damien
  • 1,492
  • 10
  • 32
  • 1
    "_Simple way_" might be relative... To convert a struct to a byte array, you can either build your byte array manually from the struct values (and vice versa), or, more conveniently, you can use interop marshalling to convert structs to byte arrays and back (see here: https://stackoverflow.com/questions/3278827/how-to-convert-a-structure-to-a-byte-array-in-c). If you choose the interop marshalling approach, you might probably also need to adjust the memory layout of the struct; see here how to do that: https://www.developerfusion.com/article/84519/mastering-structs-in-c/ –  Nov 11 '18 at 06:34
  • 1
    Possible duplicate of [How to convert a structure to a byte array in C#?](https://stackoverflow.com/questions/3278827/how-to-convert-a-structure-to-a-byte-array-in-c) –  Nov 11 '18 at 07:53
  • @elgonzo the question is different and ask for the possible problematic of doing so, also the end use is different as well. – Damien Nov 11 '18 at 09:50
  • How precisely is the question different? A different end use (application scenario) is no indicator of a difference in question. (Would asking how to drive a car be everytime a different question if the use case/reason for driving a car would be different? Like "I want to drive a car myself to the cinama to watch a movie", "I want to drive a car myself to pick up groceries", "I want to drive a car myself to work". According to your reasoning the question "How to drive a car" and its answer would be different every time just because the end use is different. No...) –  Nov 11 '18 at 09:55
  • Because serialization of a data struct from C# -> C# would not pause any problem, even with type header, but would be a problem in a C# -> C communication. It also have packing directive which is not addressed on the other question @elgonzo – Damien Nov 11 '18 at 10:44
  • You didn't ask about serialization, not sure why you emphasize it now. On the second point i agree; explict struct layout is indeed not addressed by that other question and its answers. –  Nov 11 '18 at 11:50
  • Als see @bdonlan's answer at [Copying structure in C with assignment instead of memcpy()](https://stackoverflow.com/q/13284033/608639): *"Note also that although in C memcpy and structure assignment are usually equivalent, in C++ memcpy and structure assignment are not equivalent"*. [Can I use memcpy in C++ to copy classes that have no pointers or virtual functions](https://stackoverflow.com/q/3021333/608639) also looks relevant. – jww Nov 12 '18 at 07:22
  • Also, you have lots of options for putting bits on the wire... [Binary JSON](http://bsonspec.org/), Google [Protocol Buffers](https://developers.google.com/protocol-buffers/), [ASN.1 syntax](https://en.wikipedia.org/wiki/Abstract_Syntax_Notation_One), etc. – jww Nov 12 '18 at 07:24
  • @elgonzo because the code basically speaks for itself – Damien Nov 12 '18 at 11:39
  • Thanks for the other comments, I look into it – Damien Nov 12 '18 at 11:39

1 Answers1

0

The other end is communicating with a micro controller. An advantage of this, is that the structure and packing / unpacking mechanism can be a shared code between the host application and the micro-controller application.

Unfortunately, your code would work differently on a 64-bit PC vs. 32-Bit µC.

The compilers would disagree on sizeof(unsigned long), which is 4 for most microcontroller architectures and 8 on 64-bit PC. Some µC also run big endian.

Therefore it would be a lot better to write proper serialization/deserialization code.

Turbo J
  • 7,563
  • 1
  • 23
  • 43