It's missing floating points, so you'd have to figure that out for your particular machine.. But I've used the following.
/*Just for "consistency" */
#define UNPACK8(p)      ((p)[0])
#define PACK8(p,v)      (p)[0]=(v)
#define UNPACK16LE(p)   ((p)[0]|((p)[1]<<8))
#define UNPACK32LE(p)   ((p)[0]|((p)[1]<<8UL)|((p)[2]<<16UL)|((p)[3]<<24UL))
#define UNPACK64LE(p)   (((p)[0]|((p)[1]<<8ULL)|((p)[2]<<16ULL)|((p)[3]<<24ULL)) |\
                                (((p)[4]|((p)[5]<<8ULL)|((p)[6]<<16)|((p)[7]<<24ULL)) << 32ULL))
#define PACK16LE(p,v)   (p)[0]=(v);(p)[1]=(v)>>8
#define PACK32LE(p,v)   (p)[0]=(v);(p)[1]=(v)>>8UL;(p)[2]=(v)>>16UL;(p)[3]=(v)>>24UL
#define PACK64LE(p,v)   (p)[0]=(v);(p)[1]=(v)>>8ULL;(p)[2]=(v)>>16ULL;(p)[3]=(v)>>24ULL;\
                        (p)[4]=(v)>>32ULL;(p)[5]=(v)>>40ULL;(p)[6]=(v)>>48ULL;(p)[7]=(v)>>56ULL
#define UNPACK16BE(p)   ((p)[1]|((p)[0]<<8))
#define UNPACK32BE(p)   ((p)[3]|((p)[2]<<8UL)|((p)[1]<<16UL)|((p)[0]<<24UL))
#define UNPACK64BE(p)   (((p)[7]|((p)[6]<<8ULL)|((p)[5]<<16ULL)|((p)[4]<<24ULL)) |\
                                (((p)[3]|((p)[2]<<8ULL)|((p)[1]<<16)|((p)[0]<<24ULL)) << 32ULL))
#define PACK16BE(p,v)   (p)[1]=(v);(p)[0]=(v)>>8
#define PACK32BE(p,v)   (p)[3]=(v);(p)[2]=(v)>>8UL;(p)[1]=(v)>>16UL;(p)[0]=(v)>>24UL
#define PACK64BE(p,v)   (p)[7]=(v);(p)[6]=(v)>>8ULL;(p)[5]=(v)>>16ULL;(p)[4]=(v)>>24ULL;\
                        (p)[3]=(v)>>32ULL;(p)[2]=(v)>>40ULL;(p)[1]=(v)>>48ULL;(p)[0]=(v)>>56ULL
void
vapickle(uint8_t * buf, const char *fmt, va_list args)
{
        const char *fp;
        uint8_t u8;
        uint16_t u16;
        uint32_t u32;
        uint64_t u64;
        for (fp = fmt; *fp; fp++) {
                switch (*fp) {
                case 'b':
                        u8 = va_arg(args, unsigned int);
                        PACK8(buf,u8);
                        ++buf;
                        break;
                case 'S':
                        u16= va_arg(args,unsigned int);
                        PACK16BE(buf,u16);
                        buf+=2;
                        break;
                case 'I':
                        u32 = va_arg(args, unsigned int);
                        PACK32BE(buf,u32);
                        buf+=4;
                        break;
                case 'L':
                        u64 = va_arg(args, unsigned long long);
                        PACK32BE(buf,u32);
                        buf+=8;
                        break;
                case 's':
                        u16= va_arg(args,unsigned int);
                        PACK16LE(buf,u16);
                        buf+=2;
                        break;
                case 'i':
                        u32 = va_arg(args, unsigned int);
                        PACK32LE(buf,u32);
                        buf+=4;
                        break;
                case 'l':
                        u64 = va_arg(args, uint64_t);
                        PACK32LE(buf,u64);
                        buf+=8;
                        break;
                case ' ':
                        ++buf;
                        break;
                }
        }
}
void
pickle(uint8_t *buf, const char *fmt, ...)
{
        va_list args;
        va_start(args, fmt);
        vapickle(buf,  fmt, args);
        va_end(args);
}
void
vadepickle(const uint8_t*buf, const char *fmt, va_list args)
{
        const char *fp;
        uint8_t *u8;
        uint16_t *u16;
        uint32_t *u32;
        uint64_t *u64;
        for (fp = fmt; *fp; fp++) {
                switch (*fp) {
                case 'b':
                        u8 = va_arg(args, uint8_t*);
                        *u8 = UNPACK8(buf);
                        ++buf;
                        break;
                case 'S':
                        u16= va_arg(args, uint16_t*);
                        *u16 = UNPACK16BE(buf);
                        buf+=2;
                        break;
                case 'I':
                        u32 = va_arg(args, uint32_t*);
                        *u32 = UNPACK32BE(buf);
                        buf+=4;
                        break;
                case 'L':
                        u64 = va_arg(args, uint64_t*);
                        *u64 = UNPACK32BE(buf);
                        buf+=8;
                        break;
                case 's':
                        u16 = va_arg(args,uint16_t*);
                        *u16 = UNPACK16LE(buf);
                        buf+=2;
                        break;
                case 'i':
                        u32 = va_arg(args, uint32_t*);
                        *u32 = UNPACK32LE(buf);
                        buf+=4;
                        break;
                case 'l':
                        u64 = va_arg(args, uint64_t*);
                        *u64 = UNPACK32LE(buf);
                        buf+=8;
                        break;
                case ' ':
                        ++buf;
                        break;
                }
        }
}
void
depickle(const uint8_t *buf, const char *fmt, ...)
{
        va_list args;
        va_start(args, fmt);
        vadepickle(buf, fmt, args);
        va_end(args);
}
int main(void)
{
        uint32_t i = 0x123456;
        uint16_t j = 0xabab;
        uint16_t k = 0xbbab;
        uint8_t buf[8]; /* keep this big enough according to the format string */ 
        pickle(buf,"sis",j,i,k); /*s=uint16, little endian. i = uint32, litte endian, S = uint16 big endian etc.*/
        write(1,buf,sizeof buf);
        read(0,buf,sizeof buf);
        depickle(buf,"SiS",&j,&i,&k);
        return 1;
}