基于hiredis,redis C客户端封装

项目中需要用到redis就封装了一下,基于hiredis,只封装了string和哈希的部分方法。编译时加入-D__USER_LOCK__添加线程安全。

suntelRedisCli.h


#ifndef __SUNTELREDISCLI_H__
#define __SUNTELREDISCLI_H__

#include <hiredis/hiredis.h>

#ifdef __USE_LOCK__
#include <pthread.h>
#endif

#define REDIS_OK 0
#define REDIS_ERROR 0xFFFFFFFF

class CRedisCli
{
public:
    CRedisCli();
    ~CRedisCli();
    /*
    * 连接到redis server
    */
    int ConnectDB(const char *hostName,const int port);
    int ConnectDB();
    int Auth(const char *password);

    /*
    * 系统管理
    */
    int SelectDB(int no);
    int FlushDB();
    int FlushAll();

    /*
    * string类
    */
    int Set(const char *key,const char *format,...);
    int Get(const char *key,char *value);
    int Del(const char *key);

    /*
    * 哈希类
    */
    int HMSet(const char *key,const char *format,...);
    int HMGet(const char *key,size_t *elements,char **element);//返回element

    int HSetField(const char *key,const char *field,const char *format,...);
    int HGetField(const char *key,const char *field,char *value);

    int HDel(const char *key);

private:
    #ifdef __USE_LOCK__
    pthread_mutex_t m_mutex;
    #endif
    redisContext* m_context;
    redisReply*   m_reply;
    char m_redisHost[32];
    int  m_redisPort;
    char m_redisPswd[32];
};

#endif

suntelRedisCli.cpp


#include <string.h>
#include <stdio.h>
#include "suntelRedisCli.h"

CRedisCli::CRedisCli()
{
    m_context = NULL;
    m_reply = NULL;
    strcpy(m_redisHost,"127.0.0.1");
    m_redisPort = 6379;
    memset(m_redisPswd,0x00,sizeof(m_redisPswd));
#ifdef __USE_LOCK__
    pthread_mutex_init(&m_mutex, NULL);
#endif
}

CRedisCli::~CRedisCli()
{
    if(m_context)
        redisFree(m_context);
    m_reply = NULL;
#ifdef __USE_LOCK__
    pthread_mutex_destroy(&m_mutex);
#endif
}

int CRedisCli::ConnectDB(const char *hostName,const int port)
{
#ifdef __USE_LOCK__
    pthread_mutex_lock(&m_mutex);
#endif
    strncpy(m_redisHost,hostName,sizeof(m_redisHost)-1);
    m_redisPort = port;
#ifdef __USE_LOCK__
    pthread_mutex_unlock(&m_mutex);
#endif

    return ConnectDB();
}

int CRedisCli::ConnectDB()
{
    int ret = REDIS_OK;
#ifdef __USE_LOCK__
    pthread_mutex_lock(&m_mutex);
#endif
    m_context = redisConnect(m_redisHost,m_redisPort);
    if(m_context == NULL || m_context->err)
    {
        if(m_context){
            fprintf(stderr,"Connection error: %s
",m_context->errstr);
            redisFree(m_context);
            m_context = NULL;
        }
        else{
            fprintf(stderr,"Connection error: can't allocate redis context
");
        }
        ret = REDIS_ERROR;
    }
#ifdef __USE_LOCK__
    pthread_mutex_unlock(&m_mutex);
#endif
    return ret;
}
int CRedisCli::Auth(const char *password)
{
    int ret = REDIS_OK;
#ifdef __USE_LOCK__
    pthread_mutex_lock(&m_mutex);
#endif

    strncpy(m_redisPswd,password,sizeof(m_redisPswd)-1);
    m_reply = (redisReply *)redisCommand(m_context,"auth %s",m_redisPswd);

    if( m_reply == NULL || m_reply->type == REDIS_REPLY_ERROR)
    {
        if(m_reply)
        {
            fprintf(stderr,"redis error: %s
",m_reply->str);
            freeReplyObject(m_reply);
            m_reply = NULL;
        }
        else
        {
            fprintf(stderr,"redis error with null m_reply");
        }
#ifdef __USE_LOCK__
        pthread_mutex_unlock(&m_mutex);
#endif
        return REDIS_ERROR;
    }

    freeReplyObject(m_reply);
    m_reply = NULL;
#ifdef __USE_LOCK__
    pthread_mutex_unlock(&m_mutex);
#endif
    return ret;
}

int CRedisCli::SelectDB(int no)
{
    int ret = REDIS_OK;
#ifdef __USE_LOCK__
    pthread_mutex_lock(&m_mutex);
#endif

    m_reply = (redisReply *)redisCommand(m_context,"select %d",no);

    if( m_reply == NULL || m_reply->type == REDIS_REPLY_ERROR)
    {
        if(m_reply)
        {
            fprintf(stderr,"redis error: %s
",m_reply->str);
            freeReplyObject(m_reply);
            m_reply = NULL;
        }
        else
        {
            fprintf(stderr,"redis error with null m_reply");
        }
#ifdef __USE_LOCK__
        pthread_mutex_unlock(&m_mutex);
#endif
        return REDIS_ERROR;
    }

    freeReplyObject(m_reply);
    m_reply = NULL;
#ifdef __USE_LOCK__
    pthread_mutex_unlock(&m_mutex);
#endif
    return ret;
}

int CRedisCli::FlushDB()
{
    int ret = REDIS_OK;
#ifdef __USE_LOCK__
    pthread_mutex_lock(&m_mutex);
#endif
    m_reply = (redisReply *)redisCommand(m_context,"flushdb");

    if( m_reply == NULL || m_reply->type == REDIS_REPLY_ERROR)
    {
        if(m_reply)
        {
            fprintf(stderr,"redis error: %s
",m_reply->str);
            freeReplyObject(m_reply);
            m_reply = NULL;
        }
        else
        {
            fprintf(stderr,"redis error with null m_reply");
        }
#ifdef __USE_LOCK__
        pthread_mutex_unlock(&m_mutex);
#endif
        return REDIS_ERROR;
    }

    freeReplyObject(m_reply);
    m_reply = NULL;
#ifdef __USE_LOCK__
    pthread_mutex_unlock(&m_mutex);
#endif
    return ret;
}

int CRedisCli::FlushAll()
{
    int ret = REDIS_OK;
#ifdef __USE_LOCK__
    pthread_mutex_lock(&m_mutex);
#endif
    m_reply = (redisReply *)redisCommand(m_context,"flushall");

    if( m_reply == NULL || m_reply->type == REDIS_REPLY_ERROR)
    {
        if(m_reply)
        {
            fprintf(stderr,"redis error: %s
",m_reply->str);
            freeReplyObject(m_reply);
            m_reply = NULL;
        }
        else
        {
            fprintf(stderr,"redis error with null m_reply");
        }
#ifdef __USE_LOCK__
        pthread_mutex_unlock(&m_mutex);
#endif
        return REDIS_ERROR;
    }

    freeReplyObject(m_reply);
    m_reply = NULL;
#ifdef __USE_LOCK__
    pthread_mutex_unlock(&m_mutex);
#endif
    return ret;
}

int CRedisCli::Set(const char *key,const char *format,...)
{
    va_list ap;
    va_start(ap,format);
    char buf[512]={0x00};
    snprintf(buf,512,"SET %s %s",key,format);

    int ret = REDIS_OK;
#ifdef __USE_LOCK__
    pthread_mutex_lock(&m_mutex);
#endif
    m_reply = (redisReply *)redisvCommand(m_context,buf,ap);
    va_end(ap);
    if( m_reply == NULL || m_reply->type == REDIS_REPLY_ERROR)
    {
        if(m_reply)
        {
            fprintf(stderr,"redis error: %s
",m_reply->str);
            freeReplyObject(m_reply);
            m_reply = NULL;
        }
        else
        {
            fprintf(stderr,"redis error with null m_reply");
        }
#ifdef __USE_LOCK__
        pthread_mutex_unlock(&m_mutex);
#endif
        return REDIS_ERROR;
    }

    freeReplyObject(m_reply);
    m_reply = NULL;
#ifdef __USE_LOCK__
    pthread_mutex_unlock(&m_mutex);
#endif
    return ret;
}

int CRedisCli::Get(const char *key,char * value)
{
    int ret = REDIS_OK;
#ifdef __USE_LOCK__
    pthread_mutex_lock(&m_mutex);
#endif
    m_reply = (redisReply *)redisCommand(m_context,"GET %s",key);

    if( m_reply == NULL || m_reply->type == REDIS_REPLY_ERROR)
    {
        if(m_reply)
        {
            fprintf(stderr,"redis error: %s
",m_reply->str);
            freeReplyObject(m_reply);
            m_reply = NULL;
        }
        else
        {
            fprintf(stderr,"redis error with null m_reply");
        }
#ifdef __USE_LOCK__
        pthread_mutex_unlock(&m_mutex);
#endif
        return REDIS_ERROR;
    }

    if(m_reply->type == REDIS_REPLY_STRING)
    {
        strncpy(value,m_reply->str,m_reply->len);
    }

    freeReplyObject(m_reply);
    m_reply = NULL;
#ifdef __USE_LOCK__
    pthread_mutex_unlock(&m_mutex);
#endif
    return ret;
}

int CRedisCli::Del(const char *key)
{
    int ret = REDIS_OK;
#ifdef __USE_LOCK__
    pthread_mutex_lock(&m_mutex);
#endif
    m_reply = (redisReply *)redisCommand(m_context,"DEL %s",key);

    if( m_reply == NULL || m_reply->type == REDIS_REPLY_ERROR)
    {
        if(m_reply)
        {
            fprintf(stderr,"redis error: %s
",m_reply->str);
            freeReplyObject(m_reply);
            m_reply = NULL;
        }
        else
        {
            fprintf(stderr,"redis error with null m_reply");
        }
#ifdef __USE_LOCK__
        pthread_mutex_unlock(&m_mutex);
#endif
        return REDIS_ERROR;
    }

    freeReplyObject(m_reply);
    m_reply = NULL;
#ifdef __USE_LOCK__
    pthread_mutex_unlock(&m_mutex);
#endif
    return ret;
}

int CRedisCli::HMSet(const char *key,const char *format,...)
{
    va_list ap;
    va_start(ap,format);
    char buf[512]={0x00};
    snprintf(buf,512,"HMSet %s %s",key,format);
    // printf("%s
",buf);
    int ret = REDIS_OK;
#ifdef __USE_LOCK__
    pthread_mutex_lock(&m_mutex);
#endif
    m_reply = (redisReply *)redisvCommand(m_context,buf,ap);
    va_end(ap);

    if( m_reply == NULL || m_reply->type == REDIS_REPLY_ERROR)
    {
        if(m_reply)
        {
            fprintf(stderr,"redis error: %s
",m_reply->str);
            freeReplyObject(m_reply);
            m_reply = NULL;
        }
        else
        {
            fprintf(stderr,"redis error with null m_reply");
        }
#ifdef __USE_LOCK__
        pthread_mutex_unlock(&m_mutex);
#endif
        return REDIS_ERROR;
    }

    freeReplyObject(m_reply);
    m_reply = NULL;
#ifdef __USE_LOCK__
    pthread_mutex_unlock(&m_mutex);
#endif
    return ret;
}

int CRedisCli::HMGet(const char *key,size_t *elements,char **element)
{
    int ret = REDIS_OK;
#ifdef __USE_LOCK__
    pthread_mutex_lock(&m_mutex);
#endif
    m_reply = (redisReply *)redisCommand(m_context,"HGETALL %s",key);
    if( m_reply == NULL || m_reply->type == REDIS_REPLY_ERROR)
    {
        if(m_reply)
        {
            fprintf(stderr,"redis error: %s
",m_reply->str);
            freeReplyObject(m_reply);
            m_reply = NULL;
        }
        else
        {
            fprintf(stderr,"redis error with null m_reply");
        }
#ifdef __USE_LOCK__
        pthread_mutex_unlock(&m_mutex);
#endif
        return REDIS_ERROR;
    }

    if(m_reply->type == REDIS_REPLY_ARRAY)
    {
        int i = 0;
        for(i=0;i<m_reply->elements;i++)
        {
            strncpy(element[i],m_reply->element[i]->str,m_reply->element[i]->len);
        }
    }

    freeReplyObject(m_reply);
    m_reply = NULL;
#ifdef __USE_LOCK__
    pthread_mutex_unlock(&m_mutex);
#endif
    return ret;
}

int CRedisCli::HSetField(const char *key,const char *field,const char *format,...)
{
    va_list ap;
    va_start(ap,format);
    char buf[512]={0x00};
    snprintf(buf,512,"HSet %s %s %s",key,field,format);
    //printf("%s
",buf);
    int ret = REDIS_OK;
#ifdef __USE_LOCK__
    pthread_mutex_lock(&m_mutex);
#endif
    m_reply = (redisReply *)redisvCommand(m_context,buf,ap);
    va_end(ap);

    if( m_reply == NULL || m_reply->type == REDIS_REPLY_ERROR)
    {
        if(m_reply)
        {
            fprintf(stderr,"redis error: %s
",m_reply->str);
            freeReplyObject(m_reply);
            m_reply = NULL;
        }
        else
        {
            fprintf(stderr,"redis error with null m_reply");
        }
#ifdef __USE_LOCK__
        pthread_mutex_unlock(&m_mutex);
#endif
        return REDIS_ERROR;
    }

    freeReplyObject(m_reply);
    m_reply = NULL;
#ifdef __USE_LOCK__
    pthread_mutex_unlock(&m_mutex);
#endif
    return ret;
}

int CRedisCli::HGetField(const char *key,const char *field,char *value)
{
    int ret = REDIS_OK;
#ifdef __USE_LOCK__
    pthread_mutex_lock(&m_mutex);
#endif
    m_reply = (redisReply *)redisCommand(m_context,"HGET %s %s",key,field);
    if( m_reply == NULL || m_reply->type == REDIS_REPLY_ERROR)
    {
        if(m_reply)
        {
            fprintf(stderr,"redis error: %s
",m_reply->str);
            freeReplyObject(m_reply);
            m_reply = NULL;
        }
        else
        {
            fprintf(stderr,"redis error with null m_reply");
        }
#ifdef __USE_LOCK__
        pthread_mutex_unlock(&m_mutex);
#endif
        return REDIS_ERROR;
    }

    if(m_reply->type == REDIS_REPLY_STRING)
    {
        strncpy(value,m_reply->str,m_reply->len);
    }

    freeReplyObject(m_reply);
    m_reply = NULL;
#ifdef __USE_LOCK__
    pthread_mutex_unlock(&m_mutex);
#endif
    return ret;
}

int CRedisCli::HDel(const char *key)
{
    return Del(key);
}

``
编译:

g++ -shared --fIPC suntelRedisCli.cpp -o lsuntelRedisCli -lhiredis
g++ -shared --fIPC suntelRedisCli.cpp -o lsuntelRedisCli -lhiredis -D__USE_LOCK__

原文地址:https://www.cnblogs.com/cqvoip/p/8078958.html