Thread: Packing buffer to send it (casting)

  1. #1
    Disturbed Boy gustavosserra's Avatar
    Join Date
    Apr 2003
    Posts
    244

    Packing buffer to send it (casting)

    Suppose that I have a class that has only int, char and so on, I mean, does not has any pointer or class. Could I use the reinterpret class to pack it to send through a network? My problem is that the sizeof operator, used to limit the buffer size, does not alway return the true size of the class. Example:
    Code:
    class Z{
    public:
       //...
    private:
       int a;
       char b;
    };
    
    int main(){
    
       char* buffer;
       Z myClass;
       int size = sizeof(Z); //here the size will be 8, not 5
    
       buffer = new char[size];
       buffer = reinterpret_cast<char *>(&myClass);
    
       //any send routine
       //send(buffer, size, slave);
    
       return 0;
    }
    Thanks any help!
    Nothing more to tell about me...
    Happy day =)

  2. #2
    Registered User Dante Shamest's Avatar
    Join Date
    Apr 2003
    Posts
    970
    You're certain your class only has only a char and an int?
    How did you check that sizeof( Z ) returned 8?

  3. #3
    Registered User subdene's Avatar
    Join Date
    Jan 2002
    Posts
    367
    The sizeof operator is working correctly, because a pointer to any type is 32 bits because of the memory address it will store. So you have a 32 bit pointer and a 32 bit integer,which is 64 bits all together. Therefore, 64 / 8 (bits) == 8 bytes
    Be a leader and not a follower.

  4. #4
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    It is returning the true size of the class. They are padding to a 4-byte boundary so your int takes up 4 then your char takes up 1 but is padded to 4. If you're using VC++ you can use pragma to pack it to it's true size on 1 byte boundaries.

    #pragma pack(push,1) // 1-byte boundaries

    // struct...

    #pragma pack(pop) // return to previous packing size

    Check your compiler documentation to see if it supports that pragma.
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  5. #5
    Disturbed Boy gustavosserra's Avatar
    Join Date
    Apr 2003
    Posts
    244
    Code:
    #include <iostream>
    
    using namespace std;
    
    class Z{
    public:
       //...
    private:
       int a;
       char b;
    };
    
    int main(){
    
       char* buffer;
       Z myClass;
       int size = sizeof(Z); //here the size will be 8, not 5
    
       buffer = new char[size];
       buffer = reinterpret_cast<char *>(&myClass);
    
       cout << "Sending buffer of size " << size << endl;
       
       //any send routine
       //send(buffer, size, slave);
    
       cin.get();
    
       return 0;
    }
    Nothing more to tell about me...
    Happy day =)

  6. #6
    Disturbed Boy gustavosserra's Avatar
    Join Date
    Apr 2003
    Posts
    244
    Thank you MrWizard. Unfortunately there arenīt any portable methods to use this idea :-(
    But, if the programmer must program the pack function anyway, he could calcute the total size by his own. However this is also not portable :-|
    Nothing more to tell about me...
    Happy day =)

  7. #7
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    If you're sending something through a network, that implies there is a sender and a receiver which are communicating via some protocal. I don't mean transport protocal like UDP or TCP/IP, but the protocal that defines what the sender will send and how the receiver should receive it.

    A packet used in a simple protocal could be 8 bytes in size, where the first 4 bytes are a network-ordered dword, "a", the following byte is "b", and the trailing 3 bytes are reserved/unused.

    So, using this protocal on a machine that has the same byte order, you could cast the address of an instance of Z into a char* and send it along. You would also want to ensure that your compiler packs "b" in the third byte and not the fourth, however this can be easily fixed by padding out to your compilers default structure padding size (and adjusting sizeof() accordingly). Or you can use compiler specific directives to control the "packing" size of your structures.

    Also, remove the following line in your example to make it correct:
    >> buffer = new char[size];

    gg

  8. #8
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Originally posted by gustavosserra
    But, if the programmer must program the pack function anyway, he could calcute the total size by his own. However this is also not portable :-|
    It can be done in a portable way. Here are some of the tools that help:
    htonl()
    ntohl().
    There are "short" versions of those as well, and you would include a different header on non-Windows machines (of course).

    gg

  9. #9
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    Assuming it's padding at the end, you can probably do this on the receive side:

    Z *myClass;
    myClass = reinterpret_cast<Z *>(buffer);

  10. #10
    Disturbed Boy gustavosserra's Avatar
    Join Date
    Apr 2003
    Posts
    244
    Thank you all! Really helped!!!
    Nothing more to tell about me...
    Happy day =)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Print out a buffer
    By SwarfEye in forum C Programming
    Replies: 4
    Last Post: 09-08-2006, 09:32 AM
  2. writing a pack-style function, any advices?
    By isaac_s in forum C Programming
    Replies: 10
    Last Post: 07-08-2006, 08:09 PM
  3. Socket or send() problem?
    By Achy in forum C Programming
    Replies: 5
    Last Post: 06-09-2006, 01:09 PM
  4. Having Buffer Problems With Overlapped I/O --
    By Sargera in forum C++ Programming
    Replies: 0
    Last Post: 02-07-2006, 04:46 PM
  5. getline problem
    By Unregistered in forum C++ Programming
    Replies: 4
    Last Post: 10-06-2001, 09:28 AM