windows下使用C++访问redis

12 篇文章 0 订阅
刚开始在windows下使用c++访问reids各种报错,经过网上到处搜方案,终于可以在windows下访问redis了,
特将注意事项记录下来:


1.获取redis Window下的开发库源码,从github获取
windows版:https://github.com/MSOpenTech/redis/tree/2.6


2.解压下载的压缩包,进入msvs目录下,用vs2013打开RedisServer.sln解决方案


3.编译hiredis项目,生成hiredis.lib静态库




4.在自己的工程中使用c++ 访问hiredis

(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;
//}






  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值