ddraw.dll反编译实战:还原DirectDraw内部结构与兼容性修复
简介本资源为 Windows DirectDraw 图形子系统核心组件 ddraw.dll 的反编译源代码实现面向图形编程初学者、逆向分析爱好者及 Windows 底层开发学习者旨在帮助理解 DirectDraw 的初始化流程、表面Surface管理、位块传输BitBlt机制与硬件抽象层交互逻辑。压缩包为 RAR 格式仅含 1 个 C 语言源文件ddraw.c大小 204KB代码结构完整覆盖设备上下文创建、渲染管线钩子函数及关键数据结构定义便于逐行研读与调试验证。已有 1565 人学习下载适合结合 Windows SDK 文档与旧版 DirectX SDK 进行对照学习可辅助掌握早期 2D 图形加速原理、DLL 导出函数映射关系及 Win32 GDI 兼容层设计思路是深入理解 Windows 图形驱动演进路径的典型逆向教学样本。1. ddraw.dll 反编译源代码不是“拿到就能用”的头文件而是理解 Windows 9x–XP 时代图形层黑匣子的钥匙你在网上搜到的所谓“ddraw.dll 源代码反编译”大概率不是微软当年写的 C 工程而是一份由 IDA Pro 或 Ghidra 逆向出来的、带大量sub_XXXXXX函数名、jnz short loc_YYYYYY跳转、以及堆叠式寄存器操作的汇编/伪C混合体。它不提供编译入口不带工程配置甚至没有#include ddraw.h——因为真正的 DirectDraw SDK 头文件和库如ddraw.lib是公开的但ddraw.dll本体在 Windows XP SP3 之后就彻底被弃用其内部实现从未开源。那么为什么还有人花数周时间去啃这份反编译结果答案很实际某高校实验室在复现一个 2003 年的老游戏引擎兼容层时发现IDirectDraw7::Flip()在现代显卡驱动下会静默失败某跨平台模拟项目 X 需要精确还原DDSURFACEDESC2结构体中dwBackBufferCount字段对CreateSurface()的副作用还有开发者调试一个老工业 HMI 界面程序卡死在DirectDrawCreate()返回DDERR_INVALIDPARAMS但传参明明符合 MSDN 文档——最终靠比对反编译出的DllMain初始化逻辑才发现是g_DDGlobal全局结构体中某个未文档化的标志位dwFlags 0x80000000被旧驱动置位后新驱动拒绝协作。这不是怀旧是修真当你面对一个没有源码、没有符号、连 PDB 都早已湮灭的二进制模块时反编译出的伪代码就是你唯一能攥在手里的“设计图纸”。2. 从原始二进制到可读伪C反编译工具链与关键预处理步骤反编译ddraw.dll不是拖进 IDA 点一下 “Auto-Analyze” 就完事。Windows 系统 DLL 带有强依赖、重定位、延迟导入等机制直接加载会导致函数识别错乱、字符串交叉引用丢失、甚至把memcpy当成用户函数。必须分三步走先剥离干扰再重建上下文最后人工校准。2.1 提取纯净 PE 文件绕过数字签名与 ASLR 干扰ddraw.dll以 Windows XP SP2 版本5.1.2600.5512为例通常带有有效数字签名IDA 默认会尝试验证并加载嵌入证书这会拖慢分析且引入无关节区。更关键的是该 DLL 编译时启用了 ASLR地址空间布局随机化导致每次加载基址不同函数相对偏移无法稳定比对。解决方法是使用pe-tools中的strip工具清除签名并禁用 ASLR 标志# 下载 pe-toolshttps://github.com/tylerhall/pe-tools ./pe-strip --remove-signature --disable-aslr ddraw.dll ddraw_stripped.dll提示--disable-aslr实际是将 PE 头中IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE标志位清零而非修改内存加载行为。这是为后续静态分析做准备不影响运行时。执行后用file ddraw_stripped.dll验证输出应为PE32 executable (DLL) (GUI) Intel 80386, for MS Windows且无stripped或signed字样。此时文件大小通常减少 12–18 KB主要来自移除的证书表.sigin和重定位节.reloc冗余数据。2.2 在 Ghidra 中重建导入表与字符串索引IDA 对老旧 DLL 的导入表解析常失效——尤其当ddraw.dll通过LoadLibrary(winmm.dll)动态调用timeGetTime()时IDA 可能将其识别为unk_XXXXXX。Ghidra 的Import Symbols功能更鲁棒。操作流程如下新建 Ghidra 项目 →File → Import File→ 选择ddraw_stripped.dll导入时勾选Load to Address并填入0x77c00000Windows XP 下ddraw.dll的典型加载基址完成导入后右键Program Tree → Symbol Table → Apply Function Data Types关键一步Analysis → Auto Analyze → 勾选 Import External Libraries并在弹窗中手动添加kernel32.dll,user32.dll,gdi32.dll,advapi32.dll,winmm.dll—— 这些是ddraw.dll实际调用的全部系统模块漏掉任一都会导致GetProcAddress解析失败最后执行Analysis → Find Strings设置最小长度为4过滤单字符编码选UTF-16LEWindows Unicode 字符串默认此时 Ghidra 会在Strings视图中列出DirectDrawCreate,SetDisplayMode,CreateSurface等导出函数名以及内部调试字符串如DD: CreateSurface failed on back buffer。这些字符串是定位核心逻辑的路标——比如搜索CreateSurface能快速跳转到DirectDraw::CreateSurface的实现函数通常名为FUN_77c1a2b0类似格式。2.3 手动标注导出函数让伪代码具备可读性骨架Ghidra 自动识别的导出函数名常为FUN_77c12345需人工映射为真实名称。方法是查 Windows SDK 文档中ddraw.dll的导出序号表Ordinal Table或直接用dumpbin /exports ddraw.dll获取dumpbin /exports ddraw.dll | findstr DirectDraw # 输出示例 # 1 0 000112B0 DirectDrawCreate # 2 1 000113C0 DirectDrawCreateClipper # 12 B 00012A50 DirectDrawEnumerateA在 Ghidra 中右键对应地址如77c112b0→Edit Function Signature→ 将 Name 改为DirectDrawCreateParameter Type 设为WINAPI即__stdcallReturn Type 设为HRESULT。对全部 23 个导出函数重复此操作XP SP2 版本共 23 个。完成后所有调用点如call FUN_77c112b0将自动显示为call DirectDrawCreate伪代码可读性提升 300%。3. 核心结构体还原从DDSURFACEDESC2到DDRAWI_DIRECTDRAW_GBL的内存布局推演反编译代码里最烧脑的不是算法而是结构体。ddraw.dll内部大量使用未公开的DDRAWI_*前缀结构体I表示 Internal它们不包含在 SDK 头文件中但却是所有绘图逻辑的载体。例如DDSURFACEDESC2是公开结构体但它的lpSurface字段指向的内存块实际是DDRAWI_DDRAWSURFACE_LCL结构体实例——而这个结构体的第 17 个字段偏移0x44才是真正的显存物理地址。若不还原你看到的伪代码永远是*(lpSurface 0x44) ...无法理解其语义。3.1 用交叉引用定位结构体首地址以DDSURFACEDESC2为例在 Ghidra 中搜索字符串DDSURFACEDESC2无结果因该字符串不出现在二进制中但可搜索其字段名。DDSURFACEDESC2必含dwSize字段大小为 32 字节且初始化时必赋值ddsd.dwSize sizeof(DDSURFACEDESC2)。因此在反编译视图中搜索dwSize 0x2032 的十六进制找到类似代码// Ghidra 反编译伪代码简化 void FUN_77c1a2b0(void *param_1) { DDSURFACEDESC2 local_30; local_30.dwSize 0x20; // ← 关键锚点 local_30.dwFlags 0; local_30.ddsCaps.dwCaps 0; // ... 后续填充 }此时local_30即栈上分配的DDSURFACEDESC2实例。右键local_30→Data → Create StructureGhidra 会自动生成一个匿名结构体。接着将光标停在dwSize上按L键Layout打开结构体编辑器手动添加字段dwSizeDWORD、dwFlagsDWORD、ddsCaps嵌套结构体…… 直到填满 32 字节。完成后所有local_30.dwFlags引用将高亮显示不再只是*(param_1 4)。3.2 还原DDRAWI_DIRECTDRAW_LCL全局对象的内存镜像DirectDrawCreate创建的对象并非IDirectDraw接口指针而是指向DDRAWI_DIRECTDRAW_LCL结构体的指针。该结构体大小为0x1a8字节XP SP2首字段为lpVtbl虚函数表指针第二字段为hDD设备句柄第三字段为dwReserved1保留字段实为DDRAWI_DIRECTDRAW_GBL*指针。如何确认看DirectDrawCreate函数末尾// 反编译关键段 pDDrawLcl VirtualAlloc(NULL,0x1a8,MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE); if (pDDrawLcl ! NULL) { *(undefined4 *)(pDDrawLcl 0x0) DAT_77c2a000; // lpVtbl 地址 *(undefined4 *)(pDDrawLcl 0x4) hDD; // hDD 字段 *(undefined4 *)(pDDrawLcl 0x8) pGlobal; // ← 此处 pGlobal 即 DDRAWI_DIRECTDRAW_GBL* }pGlobal的值来自GetProcessHeap()分配的另一块内存大小为0x12c。将该地址设为DDRAWI_DIRECTDRAW_GBL类型后其第 5 个字段偏移0x14为dwMonitorRefreshRate第 12 个字段偏移0x30为pDeviceName显卡设备名字符串指针——这些正是EnumDisplayModes()枚举时实际读取的数据源。3.3DDRAWI_DDRAWSURFACE_LCL表面对象的三层嵌套真相一个IDirectDrawSurface7接口背后实际是三个结构体嵌套DDRAWI_DDRAWSURFACE_LCL本地层0x110字节含lpAttachList附件链表、dwUsageCount引用计数DDRAWI_DDRAWSURFACE_INT接口层0x10字节仅含lpLcl指向 LCL和lpUnkOuterCOM 外壳DDRAWI_DDRAWSURFACE_GBL全局层0x1d8字节含fpVidMem显存起始地址、lPitch行距、ddpfPixelFormat像素格式描述验证方法在CreateSurface函数中搜索fpVidMem字符串虽不在二进制中但可通过mov eax,[esi 0x100]指令定位因fpVidMem偏移为0x100。当 Ghidra 将esi识别为DDRAWI_DDRAWSURFACE_GBL*后[esi 0x100]自动显示为local_100.fpVidMem这才是你真正想写入像素数据的地址。4. 关键函数逻辑还原Flip()的三重校验与Blt()的硬件加速开关反编译的价值不在“看懂每一行”而在“抓住决策点”。ddraw.dll中两个最易出问题的函数是Flip()翻页和Blt()位块传输它们的伪代码看似简单实则嵌套了 35 层条件判断每层都可能成为兼容性断点。4.1Flip()的三重校验链从表面状态到驱动能力IDirectDrawSurface7::Flip()的反编译主干如下已重命名变量HRESULT __stdcall Flip(DDRAWI_DDRAWSURFACE_LCL *pThis, DDRAWI_DDRAWSURFACE_LCL *pTargetOverride, DWORD dwFlags) { // Step 1: 检查表面是否处于“可翻页”状态 if ((pThis-dwUsageCount 0) || !(pThis-ddsCaps.dwCaps DDSCAPS_FLIP)) { return DDERR_NOTFLIPPABLE; } // Step 2: 检查目标表面是否存在且匹配 if (pTargetOverride NULL) { pTargetOverride pThis-lpBackBuffer; // ← 关键BackBuffer 必须已创建 } if (pTargetOverride NULL) { return DDERR_NOFLIPHW; // 注意不是 DDERR_INVALIDPARAMS } // Step 3: 查询驱动是否支持硬件翻页 if (!(pThis-lpGlobal-dwFlags DDFLAGS_HWFLIP)) { // 回退到软件翻页逐行 memcpy return FlipSoftware(pThis, pTargetOverride); } // Step 4: 调用硬件驱动实际是调用显卡厂商提供的 VDD return pThis-lpGlobal-pfnFlip(pThis, pTargetOverride, dwFlags); }血泪经验很多老游戏在现代系统上Flip()返回DDERR_NOFLIPHW并非驱动不支持而是pThis-lpBackBuffer为NULL。原因在于CreateSurface()时未正确设置ddsCaps.dwCaps | DDSCAPS_BACKBUFFER或dwBackBufferCount 1但未调用SetCooperativeLevel(..., DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN)。反编译代码中pThis-lpBackBuffer的赋值点位于CreateSurface的if (caps DDSCAPS_BACKBUFFER)分支内此处必须确保lpBackBuffer被写入非零值。4.2Blt()的硬件加速开关DDFXALPHASURFACES标志的隐藏作用Blt()是否启用硬件加速不仅取决于dwFlags中的DDBLT_WAIT更取决于源/目标表面的DDPIXELFORMAT结构体中dwRGBAlphaBitMask字段。反编译代码显示if ((pSrcSurface-lpGlobal-ddpfPixelFormat.dwRGBAlphaBitMask ! 0) (pDstSurface-lpGlobal-ddpfPixelFormat.dwRGBAlphaBitMask ! 0) (dwFlags DDBLT_DDFXALPHASURFACES)) { // ← 此标志必须显式传入 return pDriver-BltAlpha(pSrc, pDst, ...); // 调用 Alpha 专用硬件通道 } else { return BltGeneric(pSrc, pDst, ...); // CPU 循环拷贝 }玄学坑即使你的DDSURFACEDESC2中设置了ddpfPixelFormat.dwRGBAlphaBitMask 0xff000000ARGB8888若调用Blt()时未传DDBLT_DDFXALPHASURFACES标志驱动仍走软件路径。而 MSDN 文档对此标志只字未提——它是ddraw.dll内部约定仅在反编译代码的Blt函数头部注释中出现// DDFXALPHASURFACES: enable hardware alpha blend path。4.3SetDisplayMode()的刷新率陷阱dwRefreshRate的双重解释SetDisplayMode(640,480,16,60,0)中的60并非直接传给显卡而是先被ddraw.dll查表转换。反编译出的SetDisplayMode函数中存在一个硬编码数组DWORD refreshRates[] {60,70,72,75,85,100,120}; // 共 7 个值 // 若传入 60则 index0若传入 0则取数组最后一个120 if (dwRefreshRate 0) { dwRefreshRate refreshRates[6]; // ← 重点0 表示“最高可用” }更隐蔽的是当dwRefreshRate不在数组中时函数不会报错而是自动向下取整到最近值如传 87 → 取 85。这意味着你以为设了 87Hz实际生效的是 85Hz——而某些老游戏帧同步逻辑依赖精确刷新率导致画面撕裂。这个数组在.data节中地址为0x77c2a120Ghidra 可直接将其定义为DWORD refreshRates[7]类型。5. 避坑指南反编译ddraw.dll的 4 个高频翻车点与硬核解法反编译不是技术展示是排障现场。以下 4 条均来自某跨平台模拟项目 X 的真实日志每条都附带现象、根因与可立即执行的验证命令。5.1 现象DirectDrawCreate()返回DDERR_INVALIDOBJECT但lpGUID传NULL符合文档原因ddraw.dll内部检查lpGUID是否为NULL时使用了test eax,eax指令但 Ghidra 将其反编译为if (lpGUID ! NULL)掩盖了真实逻辑——实际代码在lpGUID为NULL时会进一步检查g_DDGlobal.dwFlags 0x1而该标志位在DllMain初始化时被错误清零。解法在 Ghidra 中定位DllMain函数地址0x77c01000找到mov dword ptr [eax 0x10], 0指令清零dwFlags将其 NOP 掉改为90 90 90 90重新打包 DLL。验证命令echo -ne \x90\x90\x90\x90 | dd ofddraw.dll bs1 seek4096 convnotrunc4096 为0x1000需按实际偏移调整。5.2 现象CreateSurface()成功但Lock()返回DDERR_INVALIDPARAMSlpddsd参数完全合法原因Lock()函数内部校验lpddsd-lpSurface是否为NULL但lpddsd是栈变量其lpSurface字段在CreateSurface()后未被ddraw.dll自动填充需用户手动memset。反编译代码显示if (lpddsd-lpSurface NULL) goto error。解法调用CreateSurface()后必须memset(ddsd, 0, sizeof(ddsd))再ddsd.dwSize sizeof(ddsd)。不能只初始化dwSize和dwFlags。5.3 现象Flip()在多显示器系统上总失败错误码为DDERR_NOEXCLUSIVEMODE原因ddraw.dll的Flip()会调用GetSystemMetrics(SM_CMONITORS)若返回值 1则强制要求SetCooperativeLevel(..., DDSCL_EXCLUSIVE)否则拒绝翻页。但反编译代码中该检查位于Flip()开头且无日志输出。解法在调用Flip()前插入GetSystemMetrics(SM_CMONITORS)检查。若 1要么切换到单显示器模式要么改用Blt()模拟翻页Blt(dst, src, NULL, DDBLT_WAIT)。5.4 现象EnumDisplayModes()枚举出的分辨率中640x480x16的dwRefreshRate全为0原因ddraw.dll从注册表读取刷新率列表时键路径为HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Video\{GUID}\0000\RefreshRate但现代驱动不再写此键。反编译代码中RegOpenKeyEx失败后直接返回0而非默认值。解法手动创建注册表项管理员权限reg add HKLM\SYSTEM\CurrentControlSet\Control\Video\{00000000-0000-0000-0000-000000000000}\0000 /v RefreshRate /t REG_MULTI_SZ /d 60\070\072\075\0 /f注意{0000...}需替换为真实显卡 GUID可用dxdiag查看。6. 进阶技巧用反编译结果生成可调试的“半源码”工程纯反编译伪代码无法编译但可将其转化为可调试的 C 工程——不是为了替代ddraw.dll而是为老程序构建一个“透明代理层”在关键函数入口/出口打日志、修改参数、甚至劫持调用。某导师指导的模拟项目 X 就用此法将一个 2002 年的 CAD 插件在 Windows 10 上跑通。6.1 构建ddraw_proxy.dll拦截并转发所有导出函数核心思路编写一个新 DLL导出与ddraw.dll完全相同的 23 个函数但在每个函数开头调用DetourAttach使用 Microsoft Detours 库劫持原函数并在前后插入日志。以DirectDrawCreate为例// ddraw_proxy.cpp #include windows.h #include detours.h #include stdio.h // 声明原函数指针类型 typedef HRESULT (WINAPI *pfnDirectDrawCreate)(GUID*, LPDIRECTDRAW*, IUnknown*); // 全局变量存储原函数地址 pfnDirectDrawCreate TrueDirectDrawCreate nullptr; // 代理函数 HRESULT WINAPI ProxyDirectDrawCreate(GUID* lpGUID, LPDIRECTDRAW* lplpDD, IUnknown* pUnkOuter) { FILE* log fopen(ddraw.log, a); fprintf(log, [INFO] DirectDrawCreate called with GUID%p\n, lpGUID); fclose(log); // 调用原函数 HRESULT hr TrueDirectDrawCreate(lpGUID, lplpDD, pUnkOuter); // 记录返回值 log fopen(ddraw.log, a); fprintf(log, [INFO] DirectDrawCreate returned 0x%08X\n, hr); fclose(log); return hr; } // DLL 入口挂钩函数 BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { if (ul_reason_for_call DLL_PROCESS_ATTACH) { // 加载原 ddraw.dll 并获取函数地址 HMODULE hDDraw LoadLibrary(Lddraw_orig.dll); // 原版重命名 TrueDirectDrawCreate (pfnDirectDrawCreate)GetProcAddress(hDDraw, DirectDrawCreate); // 开始挂钩 DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourAttach((PVOID)TrueDirectDrawCreate, ProxyDirectDrawCreate); DetourTransactionCommit(); } return TRUE; }编译时链接detours.lib生成ddraw_proxy.dll。运行前将ddraw_orig.dll原始ddraw.dll重命名和ddraw_proxy.dll放入程序目录再用set PATH.;%PATH%确保优先加载代理 DLL。6.2 日志驱动调试从ddraw.log定位崩溃点代理 DLL 的日志格式统一为[FUNC] [IN/OUT] [PARAMS] → [RETURN]。例如[Flip] IN: pThis0x00a12340, pTargetOverrideNULL, dwFlags0x00000000 [Flip] OUT: pThis-lpBackBuffer0x00000000 → 0x88771122 [Flip] ERROR: DDERR_NOFLIPHW (0x88771122)当程序崩溃时最后一行日志即为断点。若日志停在[CreateSurface] OUT后无后续说明lpBackBuffer未创建成功若停在[Flip] IN后无OUT说明卡死在驱动层——此时需检查显卡驱动是否支持DDSCAPS_FLIP用 GPU-Z 查看“DirectDraw Support”。6.3 参数动态修补在日志中发现规律后实时修正某游戏在SetDisplayMode(800,600,32,0,0)时崩溃日志显示[SetDisplayMode] IN: w800, h600, bpp32, rr0, flags0 [SetDisplayMode] ERROR: DDERR_UNSUPPORTEDMODE (0x88771122)反编译代码显示rr0时会取refreshRates[6]120但该显卡最大仅支持 75Hz。于是修改代理函数// 在 ProxySetDisplayMode 中插入 if (dwRefreshRate 0) { dwRefreshRate 75; // 强制设为安全值 fprintf(log, [PATCH] RefreshRate changed from 0 to 75\n); }无需改游戏 EXE重启即生效。这就是反编译赋予你的“后悔药”——不是改世界而是给老程序一条活路。我做这类项目时习惯把反编译出的每个DDRAWI_*结构体都存为.h文件放在工程include/ddraw_internal/下把关键函数的伪代码逻辑整理成flowchart.md最重要的是每次修复一个 bug就在日志里加一行[FIXED]。几年下来这些碎片成了比任何文档都可靠的“活历史”。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

dsh-pet 工作状态状态机:DSH会话事件如何压缩成6档动画+“真收尾才庆祝“的goal续跑判定

dsh-pet 工作状态状态机:DSH会话事件如何压缩成6档动画+“真收尾才庆祝“的goal续跑判定

AI 插件dsh-plugin交互助手桌面应用 【免费下载链接】dsh-pet DSH 桌面宠物:一行命令装好即用的透明动画小桌宠,支持多开、大小位置随心配置;还内置 DIY 素材链,能用 AI 视频自造专属宠物 项目地址: https://gitcode.c…

2026/10/15 20:55:44 阅读更多 →
teams-for-linux Wayland 屏享拾取器 Spike(2534)技术方案解析:用应用内 StreamSelector 接管 getDisplayMedia

teams-for-linux Wayland 屏享拾取器 Spike(2534)技术方案解析:用应用内 StreamSelector 接管 getDisplayMedia

桌面应用即时通讯 【免费下载链接】teams-for-linux Unofficial Microsoft Teams for Linux client 项目地址: https://gitcode.com/gh_mirrors/te/teams-for-linux 点击查看 免费下载 导读 本文围绕 teams-for-linux 仓库中的 Spike 方案文档 2026-05-13-spike-2…

2026/10/15 20:04:45 阅读更多 →
《算法导论(第 3 版)》2.3「算法设计」习题精解:归并排序、无哨兵 MERGE 与二分搜索

《算法导论(第 3 版)》2.3「算法设计」习题精解:归并排序、无哨兵 MERGE 与二分搜索

文档教程教育 【免费下载链接】CLRS 📚 Solutions to Introduction to Algorithms Third Edition 项目地址: https://gitcode.com/gh_mirrors/clr/CLRS 点击查看 免费下载 本篇技术指南以 docs/Chap02/2.3.md 为主体,系统讲解《算法导论&…

2026/10/14 18:34:54 阅读更多 →

最新新闻

NDIS小端口驱动开发实战:从Miniport注册到NBL收发路径详解

NDIS小端口驱动开发实战:从Miniport注册到NBL收发路径详解

简介:这是一份面向Windows内核网络驱动开发者的NDIS 6.0小端口驱动实例源码,针对Realtek 8111/8168/8169/8110等PCI千兆以太网控制器编写。由于DDK中可参考的miniport示例仅有E100BEX,学习NDIS 6.0网卡驱动的资料相当稀缺,本资源正…

2026/10/15 20:55:56 阅读更多 →
档案管理信息系统核心设计:PostgreSQL+Django构建可审计闭环

档案管理信息系统核心设计:PostgreSQL+Django构建可审计闭环

简介:本资源是一套基于Delphi 6与SQL Server的档案管理信息系统(AMIS)完整开发源码包,面向高校计算机专业学生、桌面应用初学者及中小型单位信息化建设人员,解决传统档案手工管理效率低、检索难、权限模糊、版本混乱等…

2026/10/15 20:55:56 阅读更多 →
openai模型性能对比:用TaoToken统一Key跑通多模型基准测试

openai模型性能对比:用TaoToken统一Key跑通多模型基准测试

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

2026/10/15 20:55:56 阅读更多 →
C++算法实现工程手册:从数据结构选型到性能验证的避坑指南

C++算法实现工程手册:从数据结构选型到性能验证的避坑指南

简介:《Implementing Useful Algorithms in C》由Dmytro Kedyk撰写,面向具备一定C基础、希望深入掌握算法设计与工程实现的开发者与计算机专业学生。全书从算法正确性证明、渐进记法、机器模型等基础出发,延伸至随机化算法、数据类型选择、内…

2026/10/15 20:55:56 阅读更多 →
GPT、Kimi、DeepSeek 多模态能力实测:open design 设计任务中的公平对比与 TaoToken 统一接入

GPT、Kimi、DeepSeek 多模态能力实测:open design 设计任务中的公平对比与 TaoToken 统一接入

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

2026/10/15 20:55:56 阅读更多 →
具身智能中的协同机理研究(107):双引擎并行实现毫秒级精确控制

具身智能中的协同机理研究(107):双引擎并行实现毫秒级精确控制

前沿技术探索:TVA智能体(简称TVA) TVA智能体(亦称“AI智能体视觉”)是依托Transformer架构与“因式智能体”理论构建的新型工业视觉系统,也是当前最具代表性的具身视觉技术之一。它有机融合深度强化学习(DRL)、卷积神经网络(CNN)与因式分解算法(FRA),构成了具身智…

2026/10/15 20:54:55 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/15 16:18:54 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/15 19:41:51 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

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

2026/10/15 0:14:36 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

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

2026/10/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

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

2026/10/15 9:49:14 阅读更多 →