windows下redis 和 hiredis的編譯與使用


果然,高端的程序員真心是鳥都不鳥windows的,redis的客戶端找了一圈愣是沒有C++的windows版本

我要做個windows上的C++的服務器都沒辦法和redis交互

github上所有能試的我都試過了,要么是只支持unix,要么是怎么編譯都不通過,焦頭爛額中

然后我總結了網上無數的教程,附帶修復一個個編譯錯誤,總結如下

編譯環境,32位windows7,VS2013

獲取redis windows版

MS Open Technologies 官方主頁

GitHub上的MSOpenTech/redis項目地址

編譯 redis:

1.解壓到redis(文件夾名字自定義),打開msvs用vs 打開RedisServer.sln項目,編譯全部。

2.編譯完成后在DUBUG里面找5個EXE文件,分別是redis-benchmark.exe,redis-check-aof.exe,redis-check-dump.exe,redis-cli.exe,redis-server.exe

把5個EXE復制到redis的根目錄下即可(與bin文件夾同目錄),它們的作用如下:

redis-server:Redis服務器的daemon啟動程序

redis-cli:Redis命令行操作工具。也可以用telnet根據其純文本協議來操作

redis-benchmark:Redis性能測試工具,測試Redis在當前系統下的讀寫性能

redis-check-aof:數據修復

redis-check-dump:檢查導出工具

3.修改redis配置文件,根目錄下的redis.conf文件

參數介紹:

daemonize:是否以后台daemon方式運行

pidfile:pid文件位置

port:監聽的端口號

timeout:請求超時時間

loglevel:log信息級別

logfile:log文件位置

databases:開啟數據庫的數量

save * *:保存快照的頻率,第一個*表示多長時間,第三個*表示執行多少次寫操作。在一定時間內執行一定數量的寫操作時,自動保存快照。可設置多個條件。

rdbcompression:是否使用壓縮

dbfilename:數據快照文件名(只是文件名,不包括目錄)

dir:數據快照的保存目錄(這個是目錄)

appendonly:是否開啟appendonlylog,開啟的話每次寫操作會記一條log,這會提高數據抗風險能力,但影響效率。

appendfsync:appendonlylog如何同步到磁盤(三個選項,分別是每次寫都強制調用fsync、每秒啟用一次fsync、不調用fsync等待系統自己同步)

 

4.啟動redis

進入redis目錄后 開啟服務  (注意加上redis.conf)

redis-server.exe redis.conf 

這個窗口要保持開啟  關閉時redis服務會自動關閉redis會自動保存數據到硬盤 

 

5.測試使用

另外開啟一個命令行窗口 進入redis目錄下 (注意修改自己的ip)

1.redis-cli.exe -h 192.168.10.61 -p 6379 

 

編譯 hiredis(其實上面編譯全部reids的時候已經編譯過的):

1.編譯兩個lib: hiredis.lib和Win32_Interop.lib

打開從GitHub上clone下來的文件夾,打開里面的msvs文件夾中的RedisServer.sln

從解決方案資源管理器窗口編譯hiredis工程和Win32_Interop工程(調試的時候請在debug模式下編譯這兩個庫),此時便會在Debug/Release文件夾下生成這兩個工程編譯的lib

2.在自己的工程中使用

(1)添加上一步編譯的這兩個lib到工程中

(2)復制GItHub redis項目文件夾中src/Win32_Interop下所有頭文件

(3)以及deps/hiredis下所有頭文件(其中fmacros.h用src文件夾下的fmacros.h文件替代)

(4)再復制src/Win32_Interop/win32fixes.c到自己的工程目錄,包含到工程文件中

(5)調整各個文件include的路徑

(6)示例代碼

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <hiredis.h>
#define NO_QFORKIMPL //這一行必須加才能正常使用
#include <Win32_Interop\win32fixes.h>
#pragma comment(lib,"hiredis.lib")
#pragma comment(lib,"Win32_Interop.lib")

int main()
{
    unsigned int j;
    redisContext *c;
    redisReply *reply;

    struct timeval timeout = { 1, 500000 }; // 1.5 seconds
    c = redisConnectWithTimeout((char*)"127.0.0.1", 6379, timeout);
    if (c->err) {
        printf("Connection error: %s\n", c->errstr);
        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", 3, "hello", 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];

        sprintf_s(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);
            getchar();
        }
    }
    freeReplyObject(reply);

    return 0;
}

PS.可能會碰到的編譯錯誤

 

1.必須定義入口點,請在win32fixes.h之前加上#define NO_QFORKIMPL

2.各種與其他庫的使用沖突,請右擊項目->屬性->配置屬性->C/C++->代碼生成->運行庫->改成多線程調試(/MTd)或多線程(/MT)

並且在右擊項目->屬性->配置屬性->連接器->命令行中輸入/NODEFAULTLIB:libcmt.lib

3.error C4996,各種unsafe報錯啊,請右擊項目->屬性->配置屬性->C/C++->預處理器->預處理器定義->添加“_CRT_SECURE_NO_WARNINGS”(不帶引號)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM