Home     |     .Net Programming    |     cSharp Home    |     Sql Server Home    |     Javascript / Client Side Development     |     Ajax Programming

Ruby on Rails Development     |     Perl Programming     |     C Programming Language     |     C++ Programming     |     IT Jobs

Python Programming Language     |     Laptop Suggestions?    |     TCL Scripting     |     Fortran Programming     |     Scheme Programming Language


 
 
Cervo Technologies
The Right Source to Outsource

MS Dynamics CRM 3.0

C# Programming

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.

"giddy" <gidisr@gmail.com> wrote in message

news:1180466700.180341.4670@x35g2000prf.googlegroups.com...

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

Add to del.icio.us | Digg this | Stumble it | Powered by Megasolutions Inc