Recently had to deal with similiar questions with fairly busy code. Far from ideal the basic solution I used was to create a union with several different datatypes:
typedef union myip
{
unsigned char ip8[16];
unsigned int ip32[4];
unsigned long long ip64[2];
};
Its a little quirky but worked out well. To compare two IPs just need two compares on the 64-bit integer type ip.ip64[0]==ip.ip64[0] && ip.ip64[1]=ip.ip64[1] then just add some basic functions/macros to cover needed compares.
To copy a IPv6 from an external structure directly you can use memcpy on the ip8 member or cast the structure as a pointer. ip32 was sometimes useful for IPv4 interop manipulations (IPv4 mapped IPv6 addresses) ..etc.
If you do anything other than equality remember to convert to host byte order first as the IPv6 arrays are always stored in network byte order.