前言
在項目中,我使用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;
}