Using MPI_Pack and MPI_Unpack allows you to construct very complex collections of data without using the MPI Datatypes. Because you can incrementally unpack the data by using MPI_Unpack to remove one item at a time, you can easily send data that is described by the contents of the packed data itself. For example, to send a string of characters by sending the number of characters followed by the actual characters, you could do something like

MPI_Pack( &number_of_chars, 1, MPI_INT, packbuf, MAXPACKBUF, &packsize, ...);
MPI_Pack( string, number_of_characters, MPI_CHAR, .... );

and unpack this with

MPI_Unpack( packbuf, MAXPACKBUF, &position, &number_of_chars, 1, MPI_INT, ...);
string = (char *)malloc( number_of_chars * sizeof(char) );
MPI_Unpack( packbuf, MAXPACKBUF, &position, string, number_of_characters, 
            MPI_CHAR, .... );