Naughtily loading the data members of a struct - when it's boxed

S

Steve Terepin

I have a binary file containing fixed-length records, which I
need to read into an array of structs. I've found a relatively
nice way to do this, roughly as follows (some details omitted) :

[StructLayout(LayoutKind.Explicit,Size=8)]
struct MyStruct {
[FieldOffset(0)] int field_A ;
[FieldOffset(4)] int field_B ;
}

unsafe void LoadRecord ( int jRecord, void * pStruct, int nBytes )
{
// Reads 'nBytes' bytes of data from the specified record in the file, and
// writes them to the address passed in, ie replacing the current contents
// of the struct
}

MyStruct GetMyStruct ( int jRecord )
{
MyStruct x ;
LoadRecord(jRecord,&x,8) ;
return x ;
}

This works OK, but what I'd really like to have is a completely generic
routine
that could be passed the Type of the struct, and return a newly created
instance
of that type which has been initialised by overwriting the struct fields
with data
from the file. Something like :

object GetMyGenericStruct ( int jRecord, System.Type type )
{
object tmp = System.Activator.CreateInstance(type) ;
int nBytes = System.Runtime.InteropServices.Marshal.SizeOf(type) ;
// Assuming that 'type' is typeof(MyStruct), we now have
// a 'boxed' instance of MyStruct. Problem is, how to determine
// the address of the beginning of the struct's data ?
fixed ( void * p = ?? )
{
LoadRecord(jRecord,p,nBytes) ;
}
return tmp ;
}

Is there a safe and portable way to find the correct address ?

If not, I'll just have to wait until Generics come along ... or hard code
a 'GetMyStruct' routine for each type.

Steve.
 
E

Eric Newton

This is naughty

How about putting away the unsafe code and working with the built-in
serialization framework?
 
S

Steve Terepin

Conventional serialisation isn't an option unfortunately, because the
binary data files are being generated by a C program (with a long
history). I don't like this unsafe approach either ... but reading the
bytes directly over the struct's memory does seem to work nicely (of
course, one needs to get the field offsets just right, and .Net
attributes handle this quite well). The really horrible part is even
*thinking* of trying to overwrite the fields of o struct while it's
boxed - which is soooo horrible I think .Net doesn't provide a way to do
it :)
 
E

Eric Newton

Hmmm, good point... perhaps try the GCHandle and or HandleRef classes in the
System.Runtime.InteropServices

another avenue could be the IntPtr class, all of which should give you a
hard pointer location to the structure's memory location...

HTH
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top