You are supposed to use the "Argv" flavors of redisCommand:
int redisAppendCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
void *redisCommandArgv(redisContext *c, int argc, const char **argv, const size_t *argvlen);
You need to build two arrays (pointers and sizes) before they can be called.
Something like this should work (untested):
void hmset( redisContext *c, const string &key, const map<string,string> &m )
{
vector<const char *> argv;
vector<size_t> argvlen;
static char cmd[] = "HMSET";
argv.push_back( cmd );
argvlen.push_back( sizeof(cmd)-1 );
argv.push_back( key.c_str() );
argvlen.push_back( key.size() );
map<string,string>::const_iterator i;
for ( i=m.begin(); i!=m.end(); ++i )
{
argv.push_back( i->first.c_str() );
argvlen.push_back( i->first.size() );
argv.push_back( i->second.c_str() );
argvlen.push_back( i->second.size() );
}
void *r = redisCommandArgv(c, argv.size(), &(argv[0]), &(argvlen[0]) );
if ( !r )
throw runtime_error( "Redis error" );
freeReplyObject( r );
}
Note that if your map contains a lot of items, it is a wrong idea to push it to Redis in one single command. Past N=100-1000 items, variadic commands should be split (in batches of N items) and pipelined. Keep in mind that Redis is single-threaded. When a huge command is executed, nothing else is executed. Plus, you can hit the limit of the communication buffer.