Reading a C/C data structure in C from a byte array
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
Reading a native C or C++ structure from a C# byte array is an interop problem, not just a casting problem. It only works safely when the structure layout, packing, field sizes, and endianness are all known and compatible. If any of those assumptions are wrong, the parsed data may look valid while actually being wrong.
Start with a Matching Managed Struct
If the native layout is fixed and simple, declare a C# struct with explicit layout metadata.
Pack = 1 is only correct if the native structure was packed that way. Do not guess here. Match the native definition precisely.
Read the Struct from a Byte Span
For blittable structs, MemoryMarshal.Read is a clean modern option.
This is fast and avoids manual pointer code, but it assumes the byte array matches the managed struct layout exactly.
Handle Endianness Explicitly When Needed
If the bytes come from a system or protocol with known endianness, explicit field parsing is often safer than direct struct reads.
This is more verbose, but often more robust for network or file formats.
Be Careful with Strings, Pointers, and Unions
Direct struct mapping works best for blittable numeric fields. Native pointers, variable-length strings, and unions often need custom parsing rather than a one-shot struct read.
That is the line between "interop layout match" and "protocol decoder". If the data format is complex, manual parsing is usually the safer engineering choice.
Document the Native Definition Beside the Parser
Interop code becomes fragile when the managed parser is separated from the native contract it depends on. Keep the original C or C++ definition near the C# parser, or at least document the field sizes and packing assumptions in comments or tests.
That small discipline matters because structure changes in native code are otherwise easy to miss, and the C# side may continue reading bytes without an obvious runtime failure.
Validate Size Before Reading
Before deserializing, check that the byte array is at least as large as the target structure.
This prevents partial reads from silently producing garbage values.
Common Pitfalls
- Assuming C# struct layout automatically matches a native C or C++ struct.
- Ignoring native packing and alignment rules.
- Using direct struct reads when endianness differs from the current machine.
- Treating pointers or variable-length data as if they were ordinary inline fields.
- Failing to validate byte length before attempting the read.
Interop bugs are dangerous because they can produce believable but incorrect values. Add tests with known byte patterns whenever possible. Regression tests help.
Summary
- Reading a native structure from bytes in C# only works when layout assumptions are correct.
- Use
StructLayoutcarefully and match the native packing rules exactly. - '
MemoryMarshal.Readis good for simple blittable layouts.' - Use explicit field parsing when endianness or protocol clarity matters more than brevity.
- Keep the managed parser close to the native contract it is supposed to represent.
Related reading
- Reading CSV file and storing values into an array
- Real world applications of Binary heaps and Fibonacci Heaps
- Real world examples to decide which sorting algorithm works best
- Real world implementations of classical algorithms
- Reading Excel files from C
- Reading large text files with streams in C
- Reading asynchronously from stdin with Qt
- resolve address from overloaded function stdrealfloat

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.