
简介面向Windows平台使用Redis的C/C开发者这份压缩包提供了预编译的Redis客户端库与配套头文件解决了Redis官方在Windows下编译困难的问题。包内含hiredis.lib和Win32_Interop.lib两个关键静态库分别对应32位和64位体系并区分Debug与Release运行库配置/MTD与/MT可直接链接到Visual Studio工程中省去自行编译的繁琐。压缩包共20个文件主要包括10个lib库文件、4个exe可执行程序、3个h头文件以及必要的c源文件、txt说明和dll动态库整体约6.9MB轻量易用。已有1723人学习下载。对于需要在C或C项目中集成Redis缓存、消息队列或数据库功能的开发者这份资源还附带编译配置说明和头文件可帮助快速理解hiredis的异步接口与Windows互操作层同时可作为研究Redis在Windows平台适配与跨平台开发的参考样例。1. Windows 下编译 Redis 客户端库hiredis.lib 与 Win32_Interop.lib 能帮你省下什么Windows 上做 C/C 的 Redis 客户端最卡人的往往不是业务逻辑而是「把 hiredis 从源码编出来」这一步。写中间件、做缓存治理、给老系统接数据库凡是 C 层直接操作 Redis 的场景都得先过编译这一关。这份资源把 hiredis.lib、Win32_Interop.lib 和配套头文件直接给到了手上Visual Studio 工程里配好路径就能链接跳过整个 CMake MSVC 的构建流程。它解决的是「Windows 下没有现成 Redis 客户端库」这个具体问题。新手拿它能省掉搭建编译环境的功夫熟手可以拿它当基准库对比自己用 vcpkg 或源码编译出来的结果哪里不对。启动 Redis 之后改改地址端口就能跑通 SET/GET再往业务上扩展。2. 先分清两个库hiredis 是官方客户端Win32_Interop 是服务端移植配套2.1 hiredis 是 Redis 官方的 C 客户端库hiredis 是 Redis 官方维护的 C 语言客户端GitHub 上的 hiredis 仓库就是它服务端工程里很多内部工具也直接用这一套。它做的事情可以概括成三块连接管理connect/free、命令构造与发送redisCommand 及格式化变体、回复解析redisReply 树。因为解析是库内建的你不需要自己去拼 RESP 协议报文也不用手动读写 socket对 Windows 开发者来说等于少写了一层最容易出错的网络代码。API 是典型的过程式 C 风格几个高频符号要记一下redisConnect 和 redisConnectWithTimeout 建立连接redisCommand 发命令换回复redisReply 是回复结构体type 字段标识类型。值得记住的常量有 REDIS_REPLY_STRING字符串、REDIS_REPLY_ARRAY数组遍历 elements 字段、REDIS_REPLY_INTEGER整数读 integer 字段、REDIS_REPLY_NIL空值、REDIS_REPLY_ERROR服务端报错错误信息在 str 里。写业务代码时判断 r-type 基本就是这些分支Redis 的字符串、哈希、列表这些数据类型最后都会落到这几种 reply 类型上后面最小示例里直接会用到。再说「为什么 Windows 上现成的 lib 值钱」。hiredis 官方主力构建在 Linux/macOS 上Windows 没有官方预编译包。自己编大致三条路MSVC 配 CMake、MinGW 直接编、vcpkg 装。三条路我都试过MSVC 配 CMake 最接近官方流程但要处理 CMake 版本、generator 选择这一堆啰嗦事MinGW 编出来的 lib 和 MSVC 工程互不通用vcpkg 省事但会把整个工程拖进 vcpkg 依赖体系团队协作时别人还得跟着装。相比之下直接拿一份按 MSVC 编好的静态库是投入产出比最高的选择。2.2 Win32_Interop.lib 是移植层的配套不是给客户端用的Win32_Interop 这个名字Windows 移植版老用户不会陌生。社区常用的 Windows 版 Redistporadowski/redis 这个工程用得最多为了把服务端源码里依赖 POSIX 系统调用的部分搬到 Windows 上专门写了一个适配层工程就是 Win32_Interop。它把文件锁、目录遍历、时间函数这类调用映射成 Windows API服务的对象是 redis-server 本体和 hiredis 这种客户端库是两个层面的东西。库名定位什么时候需要链接典型符号hiredis.libRedis 官方 C 客户端任何要在 Windows 上连 Redis 的 C/C 工程redisConnect、redisCommand、redisFreeWin32_Interop.libWindows 移植版 server 的 POSIX 适配层编译 Windows 版 redis-server 或定制服务端模块文件锁、目录、时间相关的兼容函数这两个库经常打包出现是因为 Windows 移植工程编译 server 时会连带把 hiredis 一起编出来发布时自然放在一块。所以拿到包第一件事不是全链进去而是先确认自己要做的事落在哪一层只写客户端认准 hiredis.lib以后想自己编 Windows 版 redis-server或者想把 Redis 内嵌进自己的服务程序Win32_Interop 才真正派上用场它的作用就是让 server 源码在 MSVC 下顺利过编译、过链接。3. 链接 hiredis.lib 的两种接法VS 工程配置与 CMake 写法3.1 VS 工程四处配置 一个预处理宏拿到包先确认目录结构头文件hiredis.h、read.h、sds.h 这一套在哪个目录hiredis.lib 在哪个目录。打开 Visual Studio 属性页按顺序配四处。第一C/C → 常规 → 附加包含目录填头文件目录第二链接器 → 常规 → 附加库目录填 lib 目录第三链接器 → 输入 → 附加依赖项写hiredis.lib;ws2_32.lib分号分隔第四C/C → 预处理 → 预处理定义加 HIREDIS_STATIC。第四处容易被忽略原因在避坑章细说。这里 ws2_32.lib 是很多人会漏的。hiredis 静态库在 Windows 上内部调用了 winsock 函数不把 ws2_32 链上链接阶段会报一堆 socket 函数找不到。另外养成一个习惯属性页里的 Debug 和 Release 两个配置都要检查一遍很多人只配了 Release切到 Debug 编译立刻报错。不想在属性页里来回点的话也可以在源文件顶部写#pragma comment(lib, hiredis.lib) #pragma comment(lib, ws2_32.lib)这相当于把链接器输入写在代码里换工程换机器不容易漏。不过 HIREDIS_STATIC 这个预处理定义还是在工程属性里加更稳它必须赶在 hiredis.h 被包含之前生效。3.2 最小可跑示例连接、SET、GET下面这段代码是我每次验证一个新 hiredis 包都会先跑一遍的能过就说明库本身没问题#include stdio.h #include winsock2.h #include hiredis.h int main(void) { WSADATA wsa; if (WSAStartup(MAKEWORD(2, 2), wsa) ! 0) { printf(WSAStartup 失败\n); return 1; } redisContext *ctx redisConnect(127.0.0.1, 6379); if (ctx NULL) { printf(连接失败内存分配出错\n); return 1; } if (ctx-err) { printf(连接错误%s\n, ctx-errstr); redisFree(ctx); return 1; } printf(连接成功\n); redisReply *r redisCommand(ctx, SET key_win hello); if (r NULL) { printf(SET 失败%s\n, ctx-errstr); redisFree(ctx); return 1; } printf(SET 返回类型 %d值 %s\n, r-type, r-str ? r-str : (null)); freeReplyObject(r); r redisCommand(ctx, GET key_win); if (r-type REDIS_REPLY_STRING) { printf(GET 结果%s\n, r-str); } freeReplyObject(r); redisFree(ctx); WSACleanup(); return 0; }逻辑说明WSAStartup 是 Windows socket 层的初始化有的 hiredis 版本内部会自己调但自己在入口调一次更稳WSAStartup 有引用计数重复调用不会出错。redisConnect 返回的 redisContext 是整个会话的句柄err 和 errstr 保存连接阶段的错误信息redisCommand 内部自己构造请求、读响应每条回复都要用 freeReplyObject 释放否则内存泄漏跑长了非常明显。参数说明127.0.0.1 和 6379 是默认地址端口。要设连接超时改用redisConnectWithTimeout(127.0.0.1, 6379, tv)tv 是struct timeval例如struct timeval tv {2, 0};表示 2 秒。redisCommand 的格式化字符串是 printf 风格但参数会按 Redis 协议自动转义所以字符串值里不用自己拼引号。3.3 不想用 VS 向导CMake 写法在这里团队项目或者习惯命令行构建的用 CMake 更利索cmake_minimum_required(VERSION 3.16) project(redis_demo C) set(CMAKE_C_STANDARD 99) add_executable(redis_demo main.c) target_include_directories(redis_demo PRIVATE ${CMAKE_SOURCE_DIR}/third_party/hiredis/include) target_link_libraries(redis_demo PRIVATE ${CMAKE_SOURCE_DIR}/third_party/hiredis/lib/hiredis.lib ws2_32)include 目录和 lib 路径按你解压的位置改。target_link_libraries 里直接写 .lib 的完整路径CMake 在 Windows 下会把它当静态库处理ws2_32 不用写后缀也能识别。配置命令和构建命令分别是cmake -B build -G Visual Studio 17 2022 -A x64 cmake --build build --config Release提示-G 指定 VS 版本、-A 指定架构这两个参数加上去能避免「默认生成器选了奇怪版本」的玄学问题。生成的 exe 在 build/Release 目录下。我的习惯是先把这份最小代码跑通再往工程里加业务。这样出问题的时候排查面很小——连库本身的问题还是自己代码的问题一眼就能分清。4. 测试前先有个目标 RedisWindows 原生安装与 Docker 容器两条路4.1 Windows 本机移植版安装、服务注册与关键配置hiredis.lib 只是客户端测试前得有个服务端。Windows 没有官方版 Redis社区最常用的移植版是 tporadowski/redis。下载 zip 解压后核心文件是 redis-server.exe、redis-cli.exe 和 redis.windows.conf。第一次运行直接前台启动redis-server.exe redis.windows.conf看到日志里出现 Ready to accept connections 就是启动成功。前台窗口一关服务就没了想常驻后台就注册成 Windows 服务redis-server.exe --service-install redis.windows.conf --service-name Redis redis-server.exe --service-start验证连通性用自带的 redis-cliredis-cli.exe ping返回 PONG 就是通了。注意 --service-install 只完成安装必须再执行 --service-start 才真正启动。改完配置要重启服务用net stop Redis再net start Redis或者 sc.exe 命令。redis.windows.conf 里有几个参数值得提前改port 默认 6379bind 默认 127.0.0.1 只能本机连protected-mode yes 在非本机访问时会有额外限制requirepass 设密码maxmemory 设个上限防止测试机器内存被打满appendonly 决定要不要开 AOF 持久化。设了密码之后上面最小示例要多一步认证redisReply *r redisCommand(ctx, AUTH %s, yourpassword); if (r-type REDIS_REPLY_ERROR) { printf(认证失败%s\n, r-str); } freeReplyObject(r);4.2 Docker 快速起一个测试容器开发机装了 Docker Desktop 的话起测试环境更快而且不会污染本机系统。三条命令足够docker run --name redis-test -p 6379:6379 -d redis:7-alpine docker exec -it redis-test redis-cli ping docker logs redis-test第一行把容器里的 6379 映射到本机第二行进容器验证第三行看启动日志排错。要带密码启动在镜像后面直接跟参数docker run --name redis-test -p 6379:6379 -d redis:7-alpine redis-server --requirepass 123456Docker 方案适合快速开一个干净环境验证客户端行为想测主从关系也能用 docker-compose 一键拉起来redis 镜像现成的配置改改就能用。但 Windows 上 Docker Desktop 的磁盘 IO 和时延跟 Linux 裸机差一个量级生产环境不建议这么跑真要长期常驻要么用原生移植版注册服务要么直接把服务端放 Linux。开发联调阶段两条路哪个顺手用哪个。5. 链接与运行期的常见坑从 _imp的 LNK2019 到命令超时5.1 _imp前缀的 LNK2019头文件默认按 DLL 声明现象编译没问题链接时报unresolved external symbol __imp_redisConnect后面跟着 __imp_redisCommand 一串。原因较新版本的 hiredis.h 在 Windows 下默认按 DLL 方式声明函数编译器生成对 _imp开头符号的引用但你手上的 hiredis.lib 是静态库里面只有 redisConnect 这个本名没有 _imp导出版两边对不上。解决工程预处理定义里加上 HIREDIS_STATIC让函数声明走静态路径然后重新编译一遍。加了之后如果还有 _imp残留检查是不是 hiredis.h 被别的地方提前包含了预处理定义要全局生效。5.2 connect、closesocket 找不到漏了 ws2_32.lib现象链接错误集中在 connect、closesocket、WSAStartup、freeaddrinfo 这几个 winsock 函数上跟 hiredis 自己的符号反而没关系。原因hiredis 静态库在 Windows 上使用了 winsock 实现这些符号不在 hiredis.lib 里而在系统库 ws2_32.lib 里。你只加了 hiredis.lib没把 ws2_32 带进来。解决VS 工程在附加依赖项里补ws2_32.libCMake 工程在 target_link_libraries 里加 ws2_32。这个坑在 Linux 上不存在所以很多从 Linux 迁过来的工程最容易踩。5.3 LNK2038 或 LNK1112架构与运行时不匹配现象报LNK2038 mismatch detected for RuntimeLibrary或者LNK1112 module machine type x64 conflicts with target machine type x86。原因hiredis.lib 是 x64 架构、按 /MD 运行时编的你的工程却是 x86 平台或者 Debug 工程用了 /MTd 运行库两边对不上。解决先在 VS 配置管理器里把活动平台切成 x64再检查 C/C → 代码生成 → 运行库统一成 /MD。Debug 联调时最好直接找 Debug 版 lib拿 Release 库硬链 Debug 工程轻则告警重则直接 LNK2038。5.4 连接正常但命令超时阻塞命令撞上 socket 读超时现象redisConnect 成功一执行 BLPOP 这类阻塞命令几秒后 redisCommand 返回 NULLerrstr 是 Connection timed out。网上搜「redis command timed out」能看到一大堆记录服务端日志里却没有异常。原因hiredis 的超时是 socket 层面的读写超时不是 Redis 命令执行超时。客户端在 connect 或 redisSetTimeout 时设了短超时比如 2 秒BLPOP 本来就要阻塞 30 秒读超时先到连接被客户端主动断开。解决连接时用 redisConnectWithTimeout 设合理连接超时连接成功后用 redisSetTimeout 把该连接的读超时拉长把阻塞操作和普通操作拆到两条连接上避免互相影响。另外先确认服务端没开 protected-mode 拦截外部连接用 redis-cli ping 验证网络再查客户端配置。提示遇到超时先打印 ctx-errstr 再动手改代码errstr 会明确告诉你到底是连不上还是读超时比瞎猜快得多。5.5 把 Win32_Interop.lib 一起链了结果符号冲突现象只写客户端图省事把包里的两个 lib 都加进依赖链接时冒出一堆不认识的符号或者出现重复定义。原因Win32_Interop.lib 是服务端移植层的适配库符号都跟 redis-server 编译相关跟客户端半毛钱关系没有链进来就是添乱。解决客户端工程只链 hiredis.lib。拿不准某个 lib 是什么用命令看符号一条命令就够dumpbin /symbols hiredis.lib | findstr redisConnecthiredis 里能搜到 redisConnect、redisCommand 这种搜出来全是不认识的适配函数说明链错对象了。6. 进阶把 hiredis 用成分布式锁以及新库到手的三件套自检6.1 用 SET NX EX 写一个最简分布式锁redisCommand 的格式化参数会按协议转义这正好用来实现分布式锁。分布式锁的核心原语是「原子地不存在才写入 带过期时间」对应 Redis 的SET key value NX EX secondsredisReply *r redisCommand(ctx, SET lock:%s %s NX EX %d, order-1001, worker-3, 10); if (r-type REDIS_REPLY_STATUS strcmp(r-str, OK) 0) { /* 成功拿到锁 */ } else if (r-type REDIS_REPLY_NIL) { /* 锁已被别人持有 */ } freeReplyObject(r);NX 保证 key 不存在时才写入EX 10 让锁最多持有 10 秒进程挂了也自动过期不会死锁。value 建议用随机串释放时配合 Lua 脚本先比较再删除避免误删别人刚拿到的锁。这个写法比我以前「先 EXISTS 再 SET」两步走强多了——两步之间锁被抢走分布式场景下就是经典踩坑点。6.2 验证新拿到的 lib 是否靠谱三件套一个编译好的 .lib 是否和工程匹配别等到链接报错才回头查。我现在拿到任何别人编好的库都强制走三件套dumpbin /headers 看 machine 是不是 x64dumpbin /symbols 看函数符号是不是静态导出、有没有 _imp前缀最后把 3.2 的最小读写 demo 编译跑一遍SET/GET 都通过才算验收。三件套里前两步是命令行的事第三步就是几分钟的事加起来不到十分钟但从根上排除了架构、运行时、符号声明这三类最隐蔽的问题。从那以后我每次拿到新的库包都强制走一遍「架构检查 → 符号检查 → 最小读写」确实帮我少踩了无数次 LNK2038 和 _imp的坑。这套流程你直接拿去用希望帮到你。本文还有配套的精品资源点击获取