|
|
 |
 |
 |
 |
what does StructLayoutAttribute.Pack do!??
hi , I' know what the StructLayoutAttribute does. I've seen it being used. But what does the Pack field do!? This is what MSDN says: Controls the alignment of data fields of a class or structure in memory. This field indicates the packing size that should be used when the LayoutKind.Sequential value is specified. The value of Pack must be 0, 1, 2, 4, 8, 16, 32, 64, or 128. A value of 0 indicates that the packing alignment is set to the default for the current platform. I dont get it! I've searched this forum and google. Got nothing , could someone please explain it with perhaps an example!? Thanks Gideon
On Tue, 29 May 2007 12:25:00 -0700, giddy <gidisr @gmail.com> wrote: > I' know what the StructLayoutAttribute does. I've seen it being used. > But what does the Pack field do!? "Packing" refers to how fields within a structure are aligned, in terms of bytes. If the packing is just 1 byte, then there are no gaps between fields. But at higher values for the packing, each field is aligned to make sure it starts on an offset relative to the beginning of the structure that is a multiple of the given packing value. If a given field is after a field that is not itself a multiple of the packing number in size, then enough bytes will be inserted to make sure that given field starts at an byte offset that *is* a multiple of the packing number. For example, consider this structure: struct A { byte b1; byte b2; } The field b1 will always be at offset 0. But the field b2 could be at a variety of offsets, depending on the packing. If the packing is 1, then b2 will be at offset 1, right after field b1. But if packing is (for example) 4, the b2 will be at offset 4. If you had more fields in the above structure before b2, then b2 would wind up at different offsets, again depending on the packing value. Always, however, a multiple of the packing value. Pete
-----------------------------------------------Reply-----------------------------------------------
> struct A > { > byte b1; > byte b2; > }
Bad example, b2 should always be at offset 1, because a sequence of variables of the same type get treated together when packing. Instead consider: struct A { byte b1; double b2; }
And all the following comments are then correct.
> The field b1 will always be at offset 0. But the field b2 could be at a > variety of offsets, depending on the packing. If the packing is 1, then > b2 will be at offset 1, right after field b1. But if packing is (for > example) 4, the b2 will be at offset 4. > If you had more fields in the above structure before b2, then b2 would > wind up at different offsets, again depending on the packing value. > Always, however, a multiple of the packing value. > Pete
"giddy" <gidisr @gmail.com> wrote in message news:1180466700.180341.4670@x35g2000prf.googlegroups.com...
> hi , > I' know what the StructLayoutAttribute does. I've seen it being used. > But what does the Pack field do!? > This is what MSDN says: > Controls the alignment of data fields of a class or structure in > memory. > This field indicates the packing size that should be used when the > LayoutKind.Sequential value is specified. The value of Pack must be 0, > 1, 2, 4, 8, 16, 32, 64, or 128. A value of 0 indicates that the > packing alignment is set to the default for the current platform. > I dont get it! I've searched this forum and google. Got nothing , > could someone please explain it with perhaps an example!? > Thanks > Gideon
In top what others said, some remarks: - any value of Pack > 8 defaults to 8. - the size of the object/structure in memory, will be a multiple of the Pack value, unless the size of the object/structure is smaller than the Pack value in which case it's size is 4 (sizeof(int)). Following are some samples illustrating the above. 1) [StructLayout(LayoutKind.Sequential, Pack=8)] struct S { byte b1; byte b2; }
size of the struct = 4 (here on the stack). size when marshaling = 2. 2) [StructLayout(LayoutKind.Sequential, Pack=8)] struct S { byte b1; // +0 byte b2; // +1 long l1; // +8 }
size of the struct = 16 (on the stack) size when marshaling = 16. 3) [StructLayout(LayoutKind.Sequential, Pack=8)] struct S { byte b1; // +0 byte b2; // +1 long l1; // +8 int i1; // +16 }
size of the struct = 24 (on the stack) size when marshaling = 24. 4) [StructLayout(LayoutKind.Sequential, Pack=4)] struct S { byte b1; // +0 byte b2; // +1 long l1; // +4 int i1; // +12 byte b3; // +16 }
size of the struct = 20 (on the stack) size when marshaling = 20. Willy. PS. The size of the objects on the heap representing the same data is the size of the struct + 8 (or + 16 , for 64 bit versions of the application) Willy.
-----------------------------------------------Reply-----------------------------------------------
On Tue, 29 May 2007 13:03:25 -0700, Ben Voigt <r @nospam.nospam> wrote: > Bad example, b2 should always be at offset 1, because a sequence of > variables of the same type get treated together when packing. Yeah, yeah...okay. :) Thanks for the correction.
-----------------------------------------------Reply-----------------------------------------------
hi , hmm , took more than a few readings but i get it now. Thanks Can i ask whether this is useful in anyway? Also , i was looking to write binary files in the first place , or more precisly write structures to a file. I *think packing might come in handy , i wanted to write an invariable amount of three different structures to a file. (something like a little database) so i can use Pack to make all three structures the same size and then write them? Is that how its done? Was thinking of a header struct(or just a long?) that stores the number of structures written into the file? So i would increment that when everytime i add a new struct? Would this method prove inefficient if i wanted to search through the structures? Thanks Gideon
-----------------------------------------------Reply-----------------------------------------------
On Wed, 30 May 2007 06:59:48 -0700, giddy <gidisr @gmail.com> wrote: > hmm , took more than a few readings but i get it now. Thanks > Can i ask whether this is useful in anyway?
Mainly when exporting a structure (sending over the network, writing to disk, using p/invoke and interop, etc.), to ensure that the layout is consistent. People might think they could use it internally to reduce memory usage (by reducing the pack size), and in fact it might do that, but there could be a significant performance hit on some hardware, and on other hardware it may not even work due to unaligned access to the data (though I don't believe this applies to anything .NET runs on). I wouldn't use it unless I had a specific need to make sure the structure is laid out in a specific way. > Also , i was looking to write binary files in the first place , or > more precisly write structures to a file. > I *think packing might come in handy , i wanted to write an invariable > amount of three different structures to a file. (something like a > little database) so i can use Pack to make all three structures the > same size and then write them? Is that how its done?
For writing structures to a binary file, packing is indeed useful. Though, it's more about making sure a given structure is always the same, as opposed to making different structures all the same size. > Was thinking of a header struct(or just a long?) that stores the > number of structures written into the file? So i would increment that > when everytime i add a new struct? Would this method prove inefficient > if i wanted to search through the structures?
If you have multiple types of structures that can be stored in the file, you need some way of knowing what structures they are. Either they always appear in the same order, or they include some sort of header themselves that at a minimum identifies the type (via a numerical code or string or whatever). If you know what structures they are, then you know what size each structure is and there's no need to make all of the structures the same size. The only place I can see that the code might wind up signficantly simpler is if you wanted to be able to skip over some number of structures without actually looking to see what the structure type is. But for that to work you'd have to have something that indexes into the list of structures. Not impossible, but not sure how common that would be. Note that many file formats actually encode the *length* of each structure just before the structure itself. That way you don't really need to match the structure type to a size, and you can even do versioning by adding new fields to the structure but only ever reading the bytes that are actually in the file. Traversing the file is easy with such a mechanism, since all you have to do is look at the structure lengths written to the file. See TIFF, RIFF, AVI (a special case of RIFF), and other formats for examples of this. Anyway, that's a long way of saying that packing is useful when writing binary files that contain structures, but usually not for the purpose of making all the structures the same size. Pete
-----------------------------------------------Reply-----------------------------------------------
hi, > If you have multiple types of structures that can be stored in the file, > you need some way of knowing what structures they are. Either they always > appear in the same order, or they include some sort of header themselves > that at a minimum identifies the type (via a numerical code or string or > whatever). If you know what structures they are, then you know what size > each structure is and there's no need to make all of the structures the > same size.
Yea , that makes a lot of sense! But it seems i'm having trouble making the structs for the billing DB. The data is originally XML so its much more flexible. I did want to write data as XML in the first place , but then i want to compress it , and that would also be somewhat like encryption - i dont want users opening the file in notepad and editing it. Does this sound "proper"?: Write the Data as XML into a temp file first. Then compress it , and delete the temp file While reading , decompress it into a temp file again , read the XML , delete the temp file. Thanks so much Gideon
-----------------------------------------------Reply-----------------------------------------------
On Jun 1, 11:28 am, giddy <gidisr @gmail.com> wrote: <snip> > Write the Data as XML into a temp file first. Then compress it , and > delete the temp file > While reading , decompress it into a temp file again , read the XML , > delete the temp file.
What purpose does the temporary file server? Why not compress it in memory? Jon
-----------------------------------------------Reply-----------------------------------------------
hi, -Do you mean write the XML data into a stream(in memory) , then compress it and put it into a file -De compress the data again into a text stream and then read from there? yea , again that makes more sense! =S Thanks Sorry for the off topic post but: FileStream fileStream = new FileStream(filename, FileMode.Open, FileAccess.Read); GZipStream compressionStream = new GZipStream(fileStream, CompressionMode.Decompress); StreamReader reader = new StreamReader(compressionStream); XmlDocument xmlDoc = new XmlDocument(); xlmDoc.Load(reader); Is that the way it should be done?? Thanks again Gideon
-----------------------------------------------Reply-----------------------------------------------
On Fri, 01 Jun 2007 04:44:57 -0700, giddy <gidisr @gmail.com> wrote: > Sorry for the off topic post but: > FileStream fileStream = new FileStream(filename, FileMode.Open, > FileAccess.Read); > GZipStream compressionStream = new GZipStream(fileStream, > CompressionMode.Decompress); > StreamReader reader = new StreamReader(compressionStream); > XmlDocument xmlDoc = new XmlDocument(); > xlmDoc.Load(reader); > Is that the way it should be done??
Well, granted...I haven't done exactly that before. But it looks about right (and not off-topic) :). Of course, somewhere you need the equivalent code to write the compressed XML. In that case, you'll want to write the XML to a MemoryStream and then compress that stream to a disk file. Again, haven't done it myself, but I expect you've got the correct basic idea. There are some theoretical limitations regarding the maximum size of a MemoryStream, but assuming you're not writing gigabytes of data, you shouldn't run into that. Pete
|
 |
 |
 |
 |
|