尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Windows下Redis C客户端hiredis静态库编译链接与避坑实践
简介面向Windows平台的Redis预编译开发库专为需要在C/C项目中集成Redis的开发者准备Redis本是开源高性能键值存储系统常用于缓存、消息中间件等场景但原生版本主要在Linux下开发Windows环境编译门槛较高。压缩包内置两个核心静态库及其配套头文件并有C示例源码可直接在Visual Studio工程中引用免去自行编译和排查依赖的麻烦。资源共20个文件其中10个为lib文件另有4个exe、3个头文件、1个C源文件、1个说明txt和1个dll整体约6.9MB按x86、x64分目录存放分别对应32位与64位系统Release使用/MT、Debug使用/MTD运行库便于按项目构建配置选用已有1723人学习下载。hiredis可高效发送命令并解析服务器回复帮助开发者操作字符串、哈希、列表、集合等数据类型Win32_Interop主要提供Windows下的兼容性支持配合说明文档与示例源码可快速掌握客户端初始化、命令交互和链接配置流程这份预编译包既适合Windows下的Redis应用开发也可作为跨平台移植与构建优化的实用参考有效降低环境搭建成本。1. 拿到 Windows 下的 Redis 库hiredis.lib 和 Win32_Interop.lib 到底解决什么问题大部分初次接触 Windows 下编译的 Redis 库的人都会把注意力放在 hiredis.lib 上以为链接上它就算完事结果第一跑就意外。hiredis 是 Redis 官方的 C 客户端它把命令打包成 RESP 协议、解析返回结果但底层依赖的 socket 与时间函数在 Windows 上和 POSIX 并不一致所以这套产物里才会同时出现 Win32_Interop.lib。这套库解决的核心问题是让 C/C 程序在 Windows 上不必自己重写网络层和兼容层花几十行代码就完成 Redis 连接、命令发送、回复解析和资源释放。它适合内部工具、服务探活、数据搬运脚本也适合给老旧项目补一个缓存通道。但要注意它只是客户端库不包含 Redis 服务端机器上得有另外的 Redis Server 在跑。更关键的一点拿到 lib 文件不等于能跑通我在实际项目里见到的大半问题都发生在链接阶段——缺依赖库、架构不一致、运行库不匹配每一项都足够让人卡上一整天。这篇文章就按「这套库是什么 → 怎么复现编译 → 怎么接进工程 → 坑在哪 → 怎么验收」的顺序讲一遍。2. 拆开这套库hiredis.lib、Win32_Interop.lib 与头文件的依赖边界2.1 hiredis.lib 是 Redis C 客户端不是 Redis 服务端hiredis 是 Redis 官方维护的 C 客户端库源码主体由 hiredis.c、net.c、read.c、sds.c 组成。它做的事情可以概括成三层命令格式化把用户调用转成 RESP 协议的字节流、网络收发通过 socket 发送和读取、回复解析把 Redis 返回的 RESP 流拆成结构化的 redisReply。你在代码里调用的 redisCommand、redisConnect、redisFree 都属于这个库的公共 API。这套 Windows 产物里的 hiredis.lib 就是这些 C 文件编译后的静态链接库。静态库的特点是不存在运行时加载的问题你的 exe 在链接时把需要的对象代码直接拷进来最终 exe 里不依赖 hiredis.dll。这也意味着如果编译方用的运行库配置和你工程不一致问题会暴露在链接和运行阶段。标题里没有附带 hiredis.dll只有 hiredis.lib基本可以确认这套东西走的是静态链接路线。我一般会先确认一件事这个 lib 是否已经包含了 net.c 里的 Winsock 调用。如果是那么你的工程里必须额外出现 ws2_32.lib否则链接器会报大量无法解析的外部符号。这一点后面避坑章会详细展开。2.2 Win32_Interop 替 hiredis 补了哪几类 POSIX 缺口hiredis 本身是按 Linux/POSIX 环境写的代码里用到了不少 Windows 原生没有的函数和常量。Win32_Interop 在这里就是兼容层把 POSIX 接口翻译成 Windows API。常见的四类缺口如下类别POSIX 原版Windows 上的替代方案Win32_Interop 做的事Socket 初始化直接 socket()必须 WSAStartup 才能用 Winsock封装初始化逻辑避免使用方漏调时间函数gettimeofday、usleep_ftime64_s、Sleep提供统一接口超时计算才能工作字符串函数strcasecmp、strncasecmp_stricmp、_strnicmp在内部做映射或条件编译文件路径/环境变量敏感字符处理Windows 路径规则保持行为一致这个库的边界并不大但作用很关键。没有它hiredis 在 Windows 上只是能编过运行时照样会踩坑。比如你忘了调 WSAStartupredisConnect 调用 socket() 时直接返回失败错误信息还未必能准确反馈到 errstr 里。Win32_Interop 的作用就是把这些底层初始化收拢到一处。在链接顺序上我习惯把 Win32_Interop.lib 放在 hiredis.lib 后面因为 hiredis 的 obj 里有未解析符号需要它来满足。MSVC 的链接器对静态库是顺序扫描的被依赖的库放后面是基本纪律。2.3 头文件里真正必须拿全的是哪几个很多使用者拿到库包后只拷贝 hiredis.h结果编译时报一堆找不到的类型定义。hiredis 的头文件不是孤立存在的它有清晰的依赖链。hiredis.h 是主头声明了 redisContext、redisReply、redisCommand 等核心 API。read.h 里定义了 redisReader 和 readReply、redisReaderCreate 这些解析层结构hiredis.h 会引用它。sds.h 定义了 sds 这个动态字符串类型回复里的字符串数据背后就是 sds。还有 alloc.h新版本的 hiredis 把内存分配钩子放在了这里老版本则是直接 malloc。如果你拿到的是新版源码alloc.h 缺失会导致编译失败。我建议把整个 include 目录完整放进工程不要只挑一个头文件。因为它们之间存在 include 路径依赖只复制部分文件最后总是差一个而且报错信息还不直接。2.4 选型边界什么场景该用这套库什么场景劝你换hiredis 是同步阻塞客户端适合的是「发一条命令、等一个回复」这种自然模型。做后台任务、批处理脚本、内部管理工具它非常顺手。如果你要做高并发网关、或者大量异步订阅这套库用起来会很难受因为异步接口 redisAsyncContext 在 Windows 上要配合事件循环处理不当容易出现回调里的线程问题。此时更好的选择是换用其他语言生态的客户端或者基于事件循环改造。另外要注意 RESP3 协议的支持。Redis 6 以后的服务端可以切换到 RESP3但老版本编译出的 hiredis 只支持 RESP2。如果你的 Redis 服务开了 RESP3这套库解析回复时可能会出问题。遇到这种情况要么把服务端协议切回 RESP2要么找与新版本服务端匹配的 hiredis 源码重新编译。选型阶段就把这个版本兼容性想清楚省得后面推倒重来。3. 从零编出一套 Windows 下的 hiredis.libCMake 与 cl/lib 两条路线3.1 两条路线怎么选你手里的库包可能没有附带编译脚本也可能你拿到的源码是老版本、根本没有 CMakeLists.txt。常见做法是看源码根目录的文件再决定路线如果能看到 CMakeLists.txt直接走 CMake 路线它会把 hiredis 的库目标定义好生成 VS 工程一步到位如果源码是老的 Makefile 体系、还没有 CMake 支持就走 cl/lib 手工编译路线把核心 C 文件手动编一遍再打包成 lib。两种路线产出的库在使用上没有区别都是静态链接。我的建议是优先 CMake因为它能正确处理 hiredis 源码里的条件编译特别是 alloc.h 和平台宏的定义。手工路线适合在没有安装 CMake 的旧机器上应急或者你只是想把 lib 重新编一遍不想为装工具折腾。3.2 路线一CMake 生成 VS 工程并编出静态库假设源码已经在本地目录打开 VS 开发者命令行或者普通终端确认 cmake 可用然后执行cmake -S . -B build -G Visual Studio 17 2022 -A x64 cmake --build build --config Release第一行是生成阶段。-S 指定源码根目录-B 指定构建目录构建产物都集中在这个目录里方便清理。-G 指定生成器Visual Studio 17 2022 对应 VS2022如果你用的是 VS2019就改成 Visual Studio 16 2019。-A x64 是架构选项想编 32 位版本就把 x64 改成 Win32。第二行是构建阶段--config Release 表示按 Release 配置编译。hiredis 的 CMakeLists 通常会生成动态库目标 hiredis 和静态库目标 hiredis_static。构建完成后在 build/Release 目录下找 hiredis_static.lib这就是我们要的静态库如果只看到了 hiredis.lib它也可能是动态库配套的导入库需要同时确认有没有 hiredis.dll。判断方法看下一步的 dumpbin。提示编译过程中如果出现 C4996 这类安全告警不用紧张这是 MSVC 对传统 C 字符串函数的常规警告不影响库本身正确性。3.3 路线二老源码没有 CMake 时的手工 cl 编译老版本的 hiredis 源码没有 CMakeLists.txt但核心 C 文件就那么几个。打开 VS 开发者命令行进到源码目录执行cl /nologo /c /O2 /MT /W3 /I. hiredis.c net.c read.c sds.c lib /nologo /out:hiredis.lib hiredis.obj net.obj read.obj sds.obj第一行是编译。/c 表示只编译不链接生成 obj 文件/O2 做速度优化/MT 指定使用静态版运行时库这和后面工程链接时选的运行库必须一致/W3 是标准警告级别/I. 表示当前目录作为头文件搜索路径。如果你拿到的源码里有 alloc.c把它也加进来。第二行是打包。/out:hiredis.lib 指定输出文件名后面按顺序列出所有 obj。这里链接器不会去解析 obj 之间的顺序但建议保持源码依赖顺序hiredis.c 引用 net.c、read.c、sds.c 的符号把被依赖的放后面。编译时可能遇到 _CRT_SECURE_NO_WARNINGS 相关的告警可以在命令行追加 /D_CRT_SECURE_NO_WARNINGS 来消除。如果源码里用了可变长数组之类的 C99 特性MSVC 会报错这种情况下只能转到 CMake 路线或者用支持 C11 的工具集。3.4 编完先验证dumpbin 看 machine 类型与依赖库编出来之后先别急着链接进工程用 dumpbin 检查一下最稳。命令如下dumpbin /headers hiredis.lib dumpbin /dependents hiredis.lib dumpbin /linkermember:1 hiredis.lib/headers 输出文件头信息重点看 FILE HEADER VALUES 里的 machinex64 会显示 8664x86 是 14C。这一项决定了这个库能不能被你的工程链接。如果工程是 x64 而库是 x86哪怕源代码完全正确链接器也直接报 LNK1112。/dependents 对静态库来说不是最关键的但如果这个 lib 实际是导入库你会看到它指向的 dll 名称。还有一个实用命令是 lib /list hiredis.lib可以列出库里的 obj 文件列表确认至少包含 hiredis.obj、net.obj、read.obj、sds.obj 这些核心对象。目的命令观察点确认架构dumpbin /headersmachine 字段 14C 为 x868664 为 x64确认是不是导入库dumpbin /dependents是否指向某个 DLL确认包含哪些对象lib /list是否包含核心 obj这套验证流程一分钟就能跑完但能省下后面链接报错后反复猜测的时间。我拿到任何第三方 Windows 库都会先做这一步再进工程。4. 把库接进 Visual Studio 工程链接配置与第一段可运行代码4.1 工程属性里需要改的三个位置库已经验证过了接下来把它接进 VS 工程。打开项目属性需要改三个地方。第一处是 C/C 常规里的附加包含目录指向库包里的头文件目录这样 #include hiredis.h 才能找到文件。第二处是链接器常规里的附加库目录指向 hiredis.lib 和 Win32_Interop.lib 所在的目录。第三处是链接器输入里的附加依赖填上完整的库名列表建议顺序如下hiredis.lib Win32_Interop.lib ws2_32.libws2_32.lib 不是库包里自带的它是 Windows SDK 的系统库凡是调用 Winsock 的程序都必须链接它。hiredis 底层用了 socket、connect、send、recv这些符号在 ws2_32.lib 里。如果你没有加它链接时会看到大量无法解析的外部符号错误代码通常是 LNK2019。另外要把运行库设置为与库一致的选项。如果库是用 /MT 编的你的工程在 C/C 代码生成里也应选多线程(/MT)如果库是 /MD工程也要同步。Debug 和 Release 配置各查一遍别只改一个。4.2 最小可运行代码WSAStartup、连接、PING、SET/GET配置完成后新建控制台工程把下面代码粘进去。这是 Windows 下用 hiredis 的最小完整链路#include stdio.h #include winsock2.h #include windows.h #include hiredis.h int main(void) { WSADATA wsaData; if (WSAStartup(MAKEWORD(2, 2), wsaData) ! 0) { printf(WSAStartup failed\n); return 1; } struct timeval tv; tv.tv_sec 3; tv.tv_usec 0; redisContext *ctx redisConnectWithTimeout(127.0.0.1, 6379, tv); if (ctx NULL) { printf(connect error: out of memory\n); WSACleanup(); return 1; } if (ctx-err) { printf(connect error: %s\n, ctx-errstr); redisFree(ctx); WSACleanup(); return 1; } redisReply *reply redisCommand(ctx, PING); if (reply NULL) { printf(command error: %s\n, ctx-errstr); } else { printf(PING - %s\n, reply-str); freeReplyObject(reply); } reply redisCommand(ctx, SET foo %s, bar); if (reply ! NULL reply-type REDIS_REPLY_STATUS) { printf(SET - %s\n, reply-str); freeReplyObject(reply); } reply redisCommand(ctx, GET foo); if (reply ! NULL reply-type REDIS_REPLY_STRING) { printf(GET - %.*s\n, (int)reply-len, reply-str); freeReplyObject(reply); } redisFree(ctx); WSACleanup(); return 0; }这段代码里有几个关键点。WSAStartup 必须出现在任何 socket 调用之前hiredis 内部不会替你调漏掉它连接会直接失败。时间结构体是 struct timeval按值传递秒和微秒要分别赋值3 秒超时就写成 tv_sec 3、tv_usec 0。虽然 Windows 的 timeval 和 POSIX 的字段定义一致但别想当然写成 double。redisConnectWithTimeout 返回 NULL 表示内存分配失败这是第一层判断。第二层是 ctx-err 非零表示网络层连接失败错误字符串在 ctx-errstr 里。注意这两层不能合并成一句因为 ctx 为 NULL 时访问 errstr 会段错误。每次 redisCommand 返回的 redisReply 都必须调用 freeReplyObject 释放。reply 为 NULL 时表示命令发送失败或连接已经断开此时错误信息在 ctx-errstr。如果 reply 不为 NULL还要判断 type比如 GET 一个不存在的 key 返回的是 REDIS_REPLY_NILstr 字段是 NULL直接打印会崩溃。printf 里用 %.*s 和 (int)reply-len是防止二进制数据里有 \0 把字符串截断也防止缓冲区越界读取。4.3 这些细节会直接影响你的第一版代码上面代码里有三个常见误用要再强调一遍。第一个是把超时参数当成整型秒数传比如 redisConnect(127.0.0.1, 6379, 3)这是错的API 不存在这个重载编译直接报错。第二个是只释放连接忘了释放 reply产生内存泄漏在长生命周期的服务代码里积累起来很可怕。第三个是格式化命令里直接拼接用户输入hiredis 的 redisCommand 支持 printf 风格格式化任何外部传入的内容都应该作为 %s 的参数而不是提前拼进命令字符串里否则特殊字符会造成命令注入。把这段代码跑通你就已经完整走过了「库接入 → 连接 → 命令 → 解析 → 释放」的全链路。接下来的避坑内容是这些操作在各种环境变化时最常翻车的地方。5. 链接级避坑5 个在 Windows 上反复出现的编译问题5.1 报 LNK2019说 WSAStartup 找不到不是库坏了是 ws2_32 没链现象链接时报一堆无法解析的外部符号比如__imp_WSAStartup、__imp_socket、__imp_connect全部集中在网络相关命名上。原因hiredis.lib 里引用了 Winsock 的 API但你的链接命令行里没有 ws2_32.lib。这不是库包损坏而是 Windows SDK 的依赖链没补齐。解决在项目属性链接器输入的附加依赖里追加 ws2_32.lib。如果是在命令行手动链接就在命令行末尾加上 ws2_32.lib。注意顺序hiredis.lib 在前ws2_32.lib 在后因为被依赖的系统库要放在引用者之后。5.2 报 LNK111232 位工程拿到了 64 位库现象链接器直接报 module machine type x64 conflicts with target machine type x86看起来像架构不匹配但很多人第一反应是清理重编工程。原因你的工程是 Win32 平台链接的 hiredis.lib 是 x64 编译产物或者反过来。MSVC 对架构匹配是零容忍的junior 开发最容易在这里浪费一上午。解决确认库的架构后用工具核对和解决。我的习惯是两步走先看工程平台是否选对了再看库本身用 dumpbin /headers 看 machine 字段x86 是 14Cx64 是 8664。如果你只有一个架构的库就把工程平台切成对应的别在配置管理器里随便新建空平台。5.3 windows.h 与 winsock2.h 的宏冲突现象编译时出现一堆重定义错误比如Winsock.h 已经有定义、error C2011: fd_set : struct type redefinition代码本身看起来没任何问题。原因Windows.h 默认会引入老版的 winsock.h而 hiredis.h 内部需要 winsock2.h两个头文件里的类型定义冲突。这是 Windows 下网络编程最著名的玄学问题之一。解决在预处理器定义里加上 WIN32_LEAN_AND_MEAN让 Windows.h 不包含 socket 相关头文件。同时如果你的工程还需要 NOMINMAX避免 windows.h 的 min/max 宏干扰 C 标准库。包含顺序上先 include winsock2.h 再 include windows.h或者直接在工程设置里把这两个宏写进预处理器定义一劳永逸。5.4 链接通过、运行崩溃MD/MT 运行库混用现象编译和链接都成功但程序一运行就崩溃报错可能是堆校验失败或者弹出关于 CRT 的断言比如_CrtIsValidHeapPointer。原因hiredis.lib 是用 /MT 编的静态 CRT你的工程用 /MD或者反过来。静态库内部持有一份运行时状态在释放跨模块分配的内存时堆管理器不是同一个崩溃就在所难免。这种情况 Debug 和 Release 混用也会出现本质是一回事。解决第一确认库编译时用的运行库选项。可以用 dumpbin /directives 看库里记录的 /DEFAULTLIB能看到 vcruntime 还是 msvcrt。第二把工程所有配置Debug、Release、x86、x64的运行库统一成库的配置。常见做法是拿到什么库就用什么配置不要试图去兼容它。5.5 一切正常但连不上 10061WSAStartup 没调或服务没起现象代码编译通过、链接通过、运行也不报错但 redisConnect 返回失败errstr 里写着 Connection refused错误码 10061或者连接超时 10060。原因分三种常见情况。第一种是 WSAStartup 没调用socket 调用失败被包装成连接错误第二种是本机 6379 端口没有 Redis 服务在监听第三种是防火墙拦了端口。解决先在命令行用 telnet 或 Test-NetConnection 验证 127.0.0.1:6379 是否通排除服务端问题。确认服务在跑之后再看代码里 WSAStartup 是否在 redisConnect 之前执行。hiredis 不会替你初始化 Winsock这是使用方必须承担的责任也是 Win32_Interop 存在的意义之一用它能把这步封装掉。6. 库链接通过之后做一层小封装并把验收变成习惯库能正常跑起来之后我强烈建议做一层薄封装把 Windows 特定的初始化收进去。别让 WSAStartup、redisFree 这些细节散落在业务代码各处。下面这个 C 封装是常见做法把生命周期和初始化关在一个类里#include winsock2.h #include windows.h #include hiredis.h class RedisClient { public: RedisClient(const char* host, int port, long timeoutSec 3) { WSAStartup(MAKEWORD(2, 2), wsaData_); struct timeval tv; tv.tv_sec timeoutSec; tv.tv_usec 0; ctx_ redisConnectWithTimeout(host, port, tv); } ~RedisClient() { if (ctx_) redisFree(ctx_); WSACleanup(); } bool ok() const { return ctx_ ! NULL ctx_-err 0; } redisContext* raw() const { return ctx_; } private: WSADATA wsaData_; redisContext* ctx_; };这个封装的价值在于构造时发起连接析构时自动释放资源WSAStartup 和 WSACleanup 也配对出现。业务代码只需要判断 ok() 再调用 raw() 去执行命令。注意析构顺序先释放 Redis 连接再清理 Winsock反过来会出问题。链接通过后还建议做一次 pipeline 验证。同步客户端每条命令都等一个 RTT在本地看不出问题连远程 Redis 时性能差异很大。用 redisAppendCommand 批量发命令、redisGetReply 成批读取是给这个库做压测的基础写法。具体代码如下redisAppendCommand(ctx, SET k1 %s, v1); redisAppendCommand(ctx, SET k2 %s, v2); redisAppendCommand(ctx, GET k1); redisReply *reply NULL; for (int i 0; i 3; i) { if (redisGetReply(ctx, (void**)reply) REDIS_OK) { if (reply) { printf(%.*s\n, (int)reply-len, reply-str); freeReplyObject(reply); } } }pipeline 里的每一层回复都必须检查 NULL 并释放一旦中间出现连接断开redisGetReply 返回的不是 REDIS_OK循环要立刻退出不能继续盲目拿 reply。验收习惯我多说一句我现在拿到任何 Windows 下的第三方库第一件事都是 dumpbin /headers 确认架构、dumpbin /dependents 确认依赖然后写一个最小场景代码跑通再进正式工程。这个习惯帮我避开了大半看起来玄学的链接期问题。库本身就那几个文件真正的复杂度全在这些编译期细节里处理好了剩下的就是熟悉的 Redis 协议调用而已。希望帮到你。本文还有配套的精品资源点击获取
RELATED

相关推荐

Spring Boot 2.0整合Quartz:从入门到生产级任务调度实践

Spring Boot 2.0整合Quartz:从入门到生产级任务调度实践

做后端这几年,定时任务几乎是每个项目都会遇到的需求,Spring Boot项目里也接过不少,像支付对账、统计报表、消息推送,都离不开任务调度。早些年很多项目直接用Spring自带的Scheduled,跑起来确实方便,但真到…

📅 2026/10/15 23:21:13
C# WebApi实战:原生WebSocket构建即时聊天与连接管理

C# WebApi实战:原生WebSocket构建即时聊天与连接管理

1. 从轮询到长连接:为什么WebApi项目最终都会走到WebSocket这一步做过WebApi的人大概都有过这样的经历:项目初期用HTTP轮询做消息通知,前端每隔几秒发一次请求问“有没有新消息”。用户量小的时候一切正常,等到同时在线人数上去之…

📅 2026/10/15 23:16:12
Open3D点云处理实战:从入门到配准重建的完整指南

Open3D点云处理实战:从入门到配准重建的完整指南

1. 点云处理的入门首选:为什么我押注Open3D搞三维视觉的,绕不开点云。不管是做自动驾驶的感知模块、工业质检的缺陷检测,还是建筑扫描的逆向建模,点云处理都是核心环节。但问题来了——点云这东西不像图像那么“规整”&#xff0c…

📅 2026/10/15 23:16:12
MORE NEWS

更多资讯

📰

C#实现平面直角坐标与极坐标转换:从数学原理到工程实践

1. 坐标系转换到底在解决什么问题平面直角坐标和极坐标,本质上是用两套完全不同的语言在描述同一个点。直角坐标说的是“你往东走3公里,再往北走4公里”,极坐标说的是“你朝东北方向走5公里”。两种说法指向同一个位置,但适用的场…

📰

Python办公文档自动化:Word与Excel创建解析实战

1. 为什么办公文档自动化是绕不开的一课做 Python 自动化的人,早晚会撞上 Office 文档这堵墙。你可能一开始只是想批量改几个 Word 里的日期,或者从一堆 Excel 里把某几列数据抠出来汇总,结果搜着搜着就掉进了python-docx、openpyxl、xlrd、p…

📰

【Cursor文档】Cursor中文官方文档教程:从VS Code迁移到AI代码库索引的完整配置指南(含TaoToken统一Key接入)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

AI 领域联邦学习通信效率优化的创新之路:TaoToken 统一 Key 通道下的参数同步调优

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

当你用来做自动化测试编排的Openclaw崩了时,对走在AI赋能软件测试前排的你有什么启事?TaoToken统一Key通道的排查清单

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

Cocos2d-x 3.0源码精读:从Ref内存管理到Renderer渲染管线

1. 这不是一本普通的技术书评,而是一份源码级的Cocos2d-x认知地图“结合源码看《我所理解的cocos2dx-3.0》—— 概述”这个标题里藏着三重信息:它不是泛泛而谈的读书笔记,而是以源码为锚点的深度解构;它聚焦的不是整个Cocos生态&a…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬