3

The exact structure of the struct is not important.

From what I gather the following c code is reading a "chunk" of binary data (equal to the size of the struct) and directly writing that to a struct (i.e first 32 bytes to name, next 2 bytes to attrib, etc). Is there any equivelent in C# managed code?

Please provide a code snipet showing similar outcome. To save time you can simplify the to only a few elements and assume the appropriate filestream type object is already initialized.

Note: I will be consuming an existing legacy data file so the formatting/packing of the existing data file is important. I can't for example just use .net serialization / deserization because I will be processing legacy existing files (changing format is not feasible).

typedef struct _PDB 
{
   char name[32];
   unsigned short attrib;
   unsigned short version;
   unsigned int created;
   unsigned int modified;
   unsigned int backup;
   unsigned int modNum;
   unsigned int nextRecordListID;
   unsigned short numRecs;
} PDB;

void getFileType(FILE *in) 
{
   PDB p;
   fseek(in, 0, SEEK_SET);
   fread(&p, sizeof(p), 1, in);
. . .
}
3
  • Are you aware that that code will break if you share files between machines with different endianess? Commented Nov 17, 2010 at 14:31
  • I hadn't thought of that but for this application it won't be an issue (all files are of a single format, created by a single legacy app, and on a single platform - Windows XP). Commented Nov 17, 2010 at 14:36
  • possible duplicate of A C# equivalent of C's fread file i/o Commented Nov 17, 2010 at 15:21

2 Answers 2

7

I think you're asking about the StructLayoutAttribute and the FieldOffsetAttribute.

Example (snippet) from MSDN site:

[StructLayout(LayoutKind.Explicit, Size=16, CharSet=CharSet.Ansi)]
public class MySystemTime 
{
   [FieldOffset(0)]public ushort wYear; 
   [FieldOffset(2)]public ushort wMonth;
   [FieldOffset(4)]public ushort wDayOfWeek; 
   [FieldOffset(6)]public ushort wDay; 
   [FieldOffset(8)]public ushort wHour; 
   [FieldOffset(10)]public ushort wMinute; 
   [FieldOffset(12)]public ushort wSecond; 
   [FieldOffset(14)]public ushort wMilliseconds; 
}
Sign up to request clarification or add additional context in comments.

3 Comments

Ok thanks that part makes sense so far. Defining the physical structure of the struct. So now how to a write to the struct directly. The equivelent of this c line: "fread(&p, sizeof(p), 1, in)" Would I just read in x bytes and then cast that as the struct?
Either this or you use the BitConverter.Toxxx method field by field - most likely there is not a large difference performance wise, but it is easier to debug.
@theUnhandledException : C# does support unions (by overlapping fields using the same code as myermian shows), so you can just add a byte array to it. The "proper" way to do it is probably with Marshal, though BinaryFormatter can be used for this purpose, too. The latter will probably stuff in metadata, so then you'd need to use BinaryFormatter to read it. Richard Taylor has an explanation of how to do this with Marshal here
2

Have a look at Marshalling, it is IMHO what you are looking for.

This link has an in-depth view of structs in C#:

http://www.developerfusion.com/article/84519/mastering-structs-in-c/

Additional info may be found at MSDN's Marshal Class documentation:

http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.aspx

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.