Click here to Skip to main content
11,804,574 members (87,820 online)
Rate this: bad
Please Sign up or sign in to vote.
See more: C# Unmanaged
Hi folks!

I have to send and receive data via TCP/IP from a legacy server. The bytes I send and receive are of course representing some data structures. In C/C++ I would memcpy the array into an existing structure or I would just cast a pointer of the strcut type to my byte array. In C it would look something like this:
#pragma pack(push, 1)

typedef struct INNER_ST
    DWORD A;
    BYTE B;
typedef struct FOO_ST
    WORD W;
    BYTE X[20];
    INNER_ST data[10];
#pragma pack(pop, 1)

void ReceiveData(const BYTE *pData)
    FOO_ST *pFooSt;
    pFooSt = (FOO_ST *)pData;
    DWORD alpha = pFooSt->data[0].A;

In C# my structures would look like this:
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct INNER_ST
    public UInt32 A;
    public Byte B;
[StructLayout(LayoutKind.Sequential, Pack = 1)]
unsafe struct FOO_ST
    public UInt16 W;
    public fixed Byte X[20];
    public fixed INNER_ST data[10]; // <- fails, Error CS1663 
    "Fixed size buffer type must be one of the following: bool, byte, short, int, long, char, sbyte, ushort, uint, ulong, float or double"

To copy "simmple" structures like INNER_ST with Marshal.PtrToStructure is not the problem.

My question: What can I do with arrays of structures inside structure to solve error CS1663.

Thx for any ideas or hints.

PS: Of course I cannot change the server side. I have the header files with the structure definitions in C and the new client will be in C#.
Posted 22-Nov-12 4:42am

1 solution

Rate this: bad
Please Sign up or sign in to vote.

Solution 1

Ignore what I posted previously, I was somewhat overcomplicating things! The method I suggested can be used when an unknown length of data is required to be marshalled.

As you know the length, it's simple:
struct Inner
    public uint A;
    public byte B;
struct Foo
    public ushort W;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)]
    public byte[] X;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
    public Inner[] data;
Why are you using fixed and unsafe?
Andy411 at 23-Nov-12 4:20am
My 5. That's it. Thx a lot. You saved my friday :-)
When I started googling about the subject most examples used fixed arrays. That's why I used fixed and unsafe. I also found some examples with the MarshalAsAttribute but they did not suit my needs. I think I also skipped the ByValArray value during reading the documentation. Now it's more clear to me.
One thing left to me is to pay attantion during construction to initialize the arrays:
Foo f = new Foo()
x = new byte[20],
data = new Inner[10],
DaveyM69 at 23-Nov-12 13:13pm
You generally only need to use fixed if the unmanaged function will mutate the data and you need it again afterwards - it prevents the GC moving the data in memory. GCHandle (when using GCHandleType.Pinned) is normally a better way for that though, or Marshal.AllocHGlobal - they both need to be freed if used so beware if you ever need them!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 OriginalGriff 3,205
1 Maciej Los 1,950
2 KrunalRohit 1,907
3 CPallini 1,855
4 Richard MacCutchan 1,187

Advertise | Privacy | Mobile
Web01 | 2.8.151002.1 | Last Updated 22 Nov 2012
Copyright © CodeProject, 1999-2015
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100