For anything complicated, check out Convert::Binary::C. It may seem daunting at first, but once you realize its power, it's an eye opener.
Update: Let me add a bit of information. You need to have a look at a specific section of the module's manpage for the prime reason to use it. I'll quote it for convenience:
Why use Convert::Binary::C?
Say you want to pack (or unpack) data
according to the following C
structure:
struct foo {
char ary[3];
unsigned short baz;
int bar;
};
You could of course use Perl's pack
and unpack functions:
@ary = (1, 2, 3);
$baz = 40000;
$bar = -4711;
$binary = pack 'c3 Si', @ary, $baz, $bar;
But this implies that the struct
members are byte aligned. If they were
long aligned (which is the default for
most compilers), you'd have to write
$binary = pack 'c3 x S x2 i', @ary, $baz, $bar;
which doesn't really increase
readability.
Now imagine that you need to pack the
data for a completely different
architecture with different byte
order. You would look into the pack
manpage again and perhaps come up with
this:
$binary = pack 'c3 x n x2 N', @ary, $baz, $bar;
However, if you try to unpack $foo
again, your signed values have turned
into unsigned ones.
All this can still be managed with
Perl. But imagine your structures get
more complex? Imagine you need to
support different platforms? Imagine
you need to make changes to the
structures? You'll not only have to
change the C source but also dozens of
pack strings in your Perl code. This
is no fun. And Perl should be fun.
Now, wouldn't it be great if you could
just read in the C source you've
already written and use all the types
defined there for packing and
unpacking? That's what
Convert::Binary::C does.