(1)设置项目属性 c/c++ -》代码生成-》运行库-》多线程调试 MTD
注:因为编译的hiredis属第三方静态库,必须跟本项目的运行库一致才不报错
(2)将库源码(github上面下载的)中deps\hiredis路径下的头文件,主要是hireids.h包含到自己的路径中 (3)将hiredis.lib, ws2_32.lib两个静态库添加到项目的依赖项中 (4)此时编译会提示类似于_strerror等未定义的错误,需要将redis-2.6\src目录下的win32fixes.h 和win32fixes.c拷贝到自己的工程目录下,并添加到工程文件中参与编译和链接 (5)此时还不够,需要定义几个宏,项目设置-》C/C++ -》预处理器,添加一下宏定义 WIN32 _DEBUG _LIB _WIN32 _CRT_SECURE_NO_WARNINGS _CRT_NONSTDC_NO_DEPRECATE _CRT_SECURE_NO_DEPRECATE (6)此时编译还会报错:error C4996, 继续项目设置:连接器 -》 命令行 中添加 /NODEFAULTLIB:libcmt.lib (7)包含头文件 时需要注意, 应该按照如下方式包含: #include "hiredis.h" #define NO_QFORKIMPL //这一行必须加才能正常使用 #include "win32fixes.h" (8) main函数中初始化网络环境 WSADATA wsaData; WSAStartup(MAKEWORD(2, 1), &wsaData); (9)现在可以开始写自己的项目代码并访问redis了注:链接库的加载、可以在项目依赖项中设置,也可以代码中编写
编译的报错,也可以在连接器中添加/NODEFAULTLIB:libcmt.lib,也可以在代码中编写
本人都是在代码中编写
以下是demo代码,vs2010下编译
头文件RedisHandle.h
#ifndef _RedisHandle_H_ #define _RedisHandle_H_ #include <stdio.h> #include "hiredis.h" #include <string> #define strcasecmp _stricmp using namespace std; #pragma comment(linker,"/NODEFAULTLIB:LIBCMT.lib") #pragma comment (lib,"hiredis.lib") /*添加socket链接库*/ #pragma comment(lib,"Ws2_32.lib") //函数声明 redisContext* connectRedis(); void testConnectRedis(); boolean setExpire(string key,int expire); boolean setExpire(string key,int expire,redisContext* context); boolean setCacheValue(string key,string value); boolean setCacheValue(string key,string value,int expire); string getCacheValue(string key); int getCacheValueLength(string key); #endif //_RedisHandle_H_ 源文件RedisHandle.cpp /* 利用微软开发的redis的接口文件hiredis操作redis 源码生成hiredis.lib引用到项目,并且必须把win32fixes.c放到源文件(即main.cpp文件中),win32fixes.c依赖win32fixes.h, 注: 1、因为hiredis.lib中引用到win32fixes.h,但是貌似没有把win32fixes.c编译到lib中,故必须在源代码中引入 2、编译的hiredis.lib的项目代码生成-》运行库-》必须跟需要用到该静态库的项目一致,debug或release方式也必须一致,否则报错 */ #include "RedisHandle.h" redisContext* connectRedis() { //redis默认监听端口为6379 可以再配置文件中修改 redisContext* c = redisConnect("127.0.0.1", 6379); if ( c->err) { redisFree(c); printf("Connect to redisServer faile\n"); //强制退出 MessageBox(NULL, TEXT("redis连接失败,服务端即将退出,请先启动redis!"), TEXT("提示"), MB_ICONWARNING); exit(0); return NULL; } printf("Connect to redisServer Success\n"); return c; } //测试连接redis void testConnectRedis() { connectRedis(); } //设置key的生命周期 boolean setExpire(string key,int expire) { return setExpire(key,expire,nullptr); } //设置key的生命周期 boolean setExpire(string key,int expire,redisContext* context) { redisContext* c = context; if(c==nullptr) { c=connectRedis(); } if(c==NULL) { return false; } char buf[10]=""; itoa(expire,buf,10); string command="expire "+key+" "+buf; redisReply* r = (redisReply*)redisCommand(c, command.c_str()); if(r->type=REDIS_REPLY_INTEGER&&r->integer==1) { return true; } return false; } //设置key的值 boolean setCacheValue(string key,string value) { return setCacheValue(key,value,NULL); } //设置key的值以及生命周期 boolean setCacheValue(string key,string value,int expire) { redisContext* c = connectRedis(); if(c==NULL) { return false; } //const char* command1 = "set stest1 value1"; string command="set "+key+" "+value; redisReply* r = (redisReply*)redisCommand(c, command.c_str()); if( NULL == r) { printf("Execut command1 failure\n"); redisFree(c); return false; } if( !(r->type == REDIS_REPLY_STATUS && strcasecmp(r->str,"OK")==0)) { printf("Failed to execute command[%s]\n",command.c_str()); freeReplyObject(r); redisFree(c); return false; } //设置生命周期 if(expire!=NULL) { if(!setExpire(key,expire,c)) { freeReplyObject(r); redisFree(c); return false; } } freeReplyObject(r); redisFree(c); printf("Succeed to execute command[%s]\n", command.c_str()); return true; } //获取key的值 string getCacheValue(string key) { redisContext* c = connectRedis(); if(c==NULL) { return ""; } string command="get "+key; //const char* command3 = "get stest1"; redisReply* r = (redisReply*)redisCommand(c, command.c_str()); //判断是否没查询到 if ( r->type == REDIS_REPLY_NIL) { printf("Failed to execute command[%s]\n",command.c_str()); freeReplyObject(r); redisFree(c); return ""; } //判断返回的是否是字符串类型 if ( r->type != REDIS_REPLY_STRING) { printf("Failed to execute command[%s]\n",command.c_str()); freeReplyObject(r); redisFree(c); return ""; } printf("The value of 'stest1' is %s\n", r->str); string value =r->str; freeReplyObject(r); redisFree(c); printf("Succeed to execute command[%s]\n", command.c_str()); return value; } //获取key的值的长度 int getCacheValueLength(string key) { redisContext* c = connectRedis(); if(c==NULL) { return -1; } string command = "strlen "+key; //const char* command2 = "strlen stest1"; redisReply* r = (redisReply*)redisCommand(c, command.c_str()); //判断返回的是否是整型 if ( r->type != REDIS_REPLY_INTEGER) { printf("Failed to execute command[%s]\n",command.c_str()); freeReplyObject(r); redisFree(c); return -1; } int length = r->integer; freeReplyObject(r); redisFree(c); printf("The length of 'stest1' is %d.\n", length); printf("Succeed to execute command[%s]\n", command.c_str()); return length; } //以秒为单位返回key的剩余时间 int getCacheValueTLL(string key) { redisContext* c = connectRedis(); if(c==NULL) { return -1; } string command = "ttl "+key; redisReply* r = (redisReply*)redisCommand(c, command.c_str()); //判断返回的是否是整型 if ( r->type != REDIS_REPLY_INTEGER) { printf("Failed to execute command[%s]\n",command.c_str()); freeReplyObject(r); redisFree(c); return -1; } int ttl = r->integer; freeReplyObject(r); redisFree(c); printf("The ttl of 'stest1' is %d.\n", ttl); printf("Succeed to execute command[%s]\n", command.c_str()); return ttl; } //int main() //{ // WSADATA wsaData; // WSAStartup(MAKEWORD(2,1), &wsaData); // setCacheValue("a","b",100); // getCacheValue("a"); // getCacheValueLength("b"); // getCacheValueTLL("a"); // getchar(); // return 0; //}