前言
在项目中,我使用Redis内存数据库的消息订阅和发布功能来实现进程间通信。在windows平台下,各种好用的库官方似乎都没有进行特定的适配。我一度以为在windows下用C/C++调用Redis会非常困难。在经过大量的查阅资料后,终于成功使用C++调用Redis,于是果断写一篇博客进行记录。
由于官方以及网络上很多人都使用的是hiredis。我也利用hiredis作为客户端。
使用记录
源码下载
去microsoft/hiredis下载windows版本的hiredis
编译工程
打开hiredis-master\msvs\vs-solutions中的sln,点击生成。
将会得到如下的文件:
在自己的项目中使用hiredis
新建项目
新建项目,项目结构如下所示(其中Debug\、x64\文件夹是生成的,可忽略):
lib文件夹包含上一步得到的.lib文件和.pdb文件。include文件夹包含hiredis\,win32_interop\和adapters\三个文件夹,分别对应hiredis-master\,msvs\win32_interop\和hiredis\adapters\下所有的.h文件。
配置项目
项目结构如下:
添加包含目录、库目录:
添加额外的依赖项:
添加编译头:
在预处理器定义中添加如下字符:_CRT_SECURE_NO_WARNINGS
修改代码生成设置:
修改头文件路径,编写main文件
main.cpp内容如下
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "include\hiredis\hiredis.h"
#define NO_QFORKIMPL
#include "win32_fixes.h"
int main(int argc, char **argv) {
unsigned int j;
redisContext *c;
redisReply *reply;
const char *hostname = (argc > 1) ? argv[1] : "127.0.0.1";
int port = (argc > 2) ? atoi(argv[2]) : 6379;
struct timeval timeout = { 1, 500000 }; // 1.5 seconds
c = redisConnectWithTimeout(hostname, port, timeout);
if (c == NULL || c->err) {
if (c) {
printf("Connection error: %s\n", c->errstr);
redisFree(c);
}
else {
printf("Connection error: can't allocate redis context\n");
}
exit(1);
}
/* PING server */
reply = (redisReply*)redisCommand(c, "PING");
printf("PING: %s\n", reply->str);
freeReplyObject(reply);
/* Set a key */
reply = (redisReply*)redisCommand(c, "SET %s %s", "foo", "hello world");
printf("SET: %s\n", reply->str);
freeReplyObject(reply);
/* Set a key using binary safe API */
reply = (redisReply*)redisCommand(c, "SET %b %b", "bar", (size_t)3, "hello", (size_t)5);
printf("SET (binary API): %s\n", reply->str);
freeReplyObject(reply);
/* Try a GET and two INCR */
reply = (redisReply*)redisCommand(c, "GET foo");
printf("GET foo: %s\n", reply->str);
freeReplyObject(reply);
reply = (redisReply*)redisCommand(c, "INCR counter");
printf("INCR counter: %lld\n", reply->integer);
freeReplyObject(reply);
/* again ... */
reply = (redisReply*)redisCommand(c, "INCR counter");
printf("INCR counter: %lld\n", reply->integer);
freeReplyObject(reply);
/* Create a list of numbers, from 0 to 9 */
reply = (redisReply*)redisCommand(c, "DEL mylist");
freeReplyObject(reply);
for (j = 0; j < 10; j++) {
char buf[64];
snprintf(buf, 64, "%d", j);
reply = (redisReply*)redisCommand(c, "LPUSH mylist element-%s", buf);
freeReplyObject(reply);
}
/* Let's check what we have inside the list */
reply = (redisReply*)redisCommand(c, "LRANGE mylist 0 -1");
if (reply->type == REDIS_REPLY_ARRAY) {
for (j = 0; j < reply->elements; j++) {
printf("%u) %s\n", j, reply->element[j]->str);
}
}
freeReplyObject(reply);
/* Disconnects and frees the context */
redisFree(c);
system("pause");
return 0;
}