It is not possible to listen on 2 different IP addresses with 1 TCP socket, however if you listen on all interfaces using the in6addr_any address, that will include all IPv4 addresses as well (though I believe e.g. linux has a kernel option to disable that mapping).
The (newer version of) socket API is quite transparent as to whether you're using IPv4 or IPv6, but quite great care must be taken over how an IPv4 application is typically coded.
e.g. this IPv4 code which accepts a connection and prints out the address of the remote host:
struct sockaddr_in client_addr;
socklen_t addr_len = sizeof(client_addr);
client_data->fd = accept(server_fd,(struct sockaddr*)&client_addr,&addr_len);
log_printf("New client from %s\n",inet_ntoa(client_addr.sin_addr.s_addr));
Would have to be converted to the following, which handles both IPv4 and IPv6
struct sockaddr_storage client_addr;
char numeric_addr[INET6_ADDRSTRLEN];
socklen_t addr_len = sizeof(client_addr);
client_data->fd = accept(server_fd,(struct sockaddr*)&client_addr,&addr_len);
if(client_addr.ss_family == AF_INET)
log_printf("New client from %s\n",inet_ntop(client_addr.ss_family,((struct sockaddr_in*)&client_addr)->sin_addr.s_addr ,numeric_addr,sizeof numeric_addr));
else if(client_addr.ss_family == AF_INET6)
log_printf("New client from %s\n",inet_ntop(client_addr.ss_family,((struct sockaddr_in6*)&client_addr)->sin6_addr ,numeric_addr,sizeof numeric_addr));
Though I believe you could do it even more elegantly and transparent with getaddrinfo()
Here's additional notes on IP layer independance:
http://uw714doc.sco.com/en/SDK_netapi/sockC.PortIPv4appIPv6.html
http://www.kame.net/newsletter/19980604/