ReactOS 图形系统分析(19):颜色转换对象 — XLATEOBJ(xlateobj.c/h)

ReactOS 图形系统分析(19):颜色转换对象 --- XLATEOBJ(xlateobj.c/h)

1. 概述

xlateobj.c / xlateobj.h 位于 win32ss/gdi/eng/,实现 XLATEOBJ(颜色转换对象) ------Windows GDI/DDI 中描述"源表面颜色 → 目标表面颜色"转换的核心对象。它解决一个本质问题:不同位深/格式/调色板的表面之间复制像素时,每个像素值如何映射

与《分析_16/17/18》不同,xlateobj 不是预留服务层,而是引擎最核心、被高频调用的模块 :DIB 引擎每个位深(1/4/8/16/24/32bpp)的 BitBlt、拉伸、Alpha 混合、文本字形上屏、画刷填充,全部经过 XLATEOBJ_iXlate 做像素级颜色转换。

复制代码
┌─────────────────────────────────────────────────────────────┐
│ 消费方                                                        │
│   DIB 引擎 (dib*.c / BitBlt 内联 XLATEOBJ_iXlate)             │
│   eng/bitblt.c (画刷/前景背景色)  dib/alphablend.c            │
│   dib/stretchblt.c   ntgdi(bitblt/fillshap/freetype/palette) │
├─────────────────────────────────────────────────────────────┤
│ gdi/eng/xlateobj.c(本分析对象)                              │
│   核心: EXLATEOBJ 结构 + pfnXlate 函数指针分发                 │
│   ├── ~25 个专用转换函数 (FN_XLATE)                           │
│   ├── EXLATEOBJ_vInitialize: 按源/目标调色板类型选择函数      │
│   └── DDI 公开: XLATEOBJ_iXlate / cGetPalette /               │
│       hGetColorTransform / piVector                           │
├─────────────────────────────────────────────────────────────┤
│ ntgdi/palette.c (调色板对象/位掩码)                           │
│   提供 gpalRGB/gpalRGB555/gpalRGB565/gppalMono 等全局调色板    │
└─────────────────────────────────────────────────────────────┘

2. 核心数据结构

2.1 XLATEOBJ --- DDI 公开部分(winddi.h(file:///d:/reactos/sdk/include/psdk/winddi.h#L1254-L1261))

c 复制代码
typedef struct _XLATEOBJ {
  ULONG   iUniq;      // 唯一编号(每次初始化递增,用于缓存命中判断)
  FLONG   flXlate;    // XO_* 标志
  USHORT  iSrcType;   // 源调色板类型
  USHORT  iDstType;   // 目标调色板类型
  ULONG   cEntries;   // 转换表项数
  ULONG  *pulXlate;   // 转换表指针(可指向内嵌数组或堆分配)
} XLATEOBJ;

2.2 EXLATEOBJ --- 引擎扩展(xlateobj.h(file:///d:/reactos/win32ss/gdi/eng/xlateobj.h#L19-L51))

c 复制代码
typedef struct _EXLATEOBJ
{
    XLATEOBJ xlo;              // 公开头

    PFN_XLATE pfnXlate;        // ← 函数指针分发核心(FASTCALL ULONG(pexlo, iColor))

    PPALETTE ppalSrc;          // 源调色板
    PPALETTE ppalDst;          // 目标调色板
    PPALETTE ppalDstDc;        // 目标 DC 调色板(DC_PALETTE 用)

    HANDLE hColorTransform;    // 颜色变换句柄(ICM)

    union                      // 6 个 ULONG 的复用池:
    {
        ULONG aulXlate[6];     // ① 内嵌小转换表(≤6 项,省去堆分配)
        struct {               // ② 位域转换参数(掩码 + 旋转偏移)
            ULONG ulRedMask;  ULONG ulGreenMask;  ULONG ulBlueMask;
            ULONG ulRedShift; ULONG ulGreenShift; ULONG ulBlueShift;
        };
        struct {               // ③ 彩色→单色转换参数(点积判别常数)
            LONG lDeltaR;  LONG lDeltaG;  LONG lDeltaB;  LONG lHalfDist;
        } ToMono;
    };
} EXLATEOBJ, *PEXLATEOBJ;

设计亮点: pfnXlate 函数指针 + 6 个 ULONG 的联合池------同一块内嵌存储按转换类型复用作"小表 / 位域掩码偏移 / 单色点积常数",避免为小转换表堆分配,且转换本身是一条快路径调用。

2.3 标志位

*XO_ 转换类型标志(winddi.h(file:///d:/reactos/sdk/include/psdk/winddi.h#L1247-L1249)):**

标志 含义
XO_TRIVIAL 恒等转换(源值即目标值)
XO_TABLE 查表转换
XO_TO_MONO 转换到单色

XO_ 调色板编号(XLATEOBJ_cGetPalette 用,winddi.h(file:///d:/reactos/sdk/include/psdk/winddi.h#L3151-L3155)): * XO_SRCPALETTE=1XO_DESTPALETTE=2XO_DESTDCPALETTE=3XO_SRCBITFIELDS=4XO_DESTBITFIELDS=5

*PAL_ 调色板类型(palette.h(file:///d:/reactos/win32ss/gdi/ntgdi/palette.h#L10-L28),节选):**

标志 含义
PAL_INDEXED 索引色(查表,含颜色表)
PAL_BITFIELDS 位域(RGB 掩码 + 偏移)
PAL_RGB / PAL_BGR 24/32bpp 直接 RGB / BGR 顺序
PAL_RGB16_555 / PAL_RGB16_565 16bpp 高/低 5 位格式
PAL_MONOCHROME 单色(仅 2 色)
PAL_DIBSECTION DIB Section 专用(转换方向特殊处理)

2.4 全局单例 gexloTrivial

c 复制代码
EXLATEOBJ gexloTrivial = {{0, XO_TRIVIAL, 0, 0, 0, 0}, EXLATEOBJ_iXlateTrivial};

恒等转换的全局实例(flXlate=XO_TRIVIAL + pfnXlate=iXlateTrivial),当无颜色转换需求时直接引用(bitblt_new.c(file:///d:/reactos/win32ss/gdi/eng/bitblt_new.c#L141)、mouse.c(file:///d:/reactos/win32ss/gdi/eng/mouse.c#L357)),避免每次分配对象。


3. 转换函数族(~25 个 FN_XLATE)

全部签名为 FASTCALL ULONG(PEXLATEOBJ, ULONG iColor),按用途分五类:

3.1 单色快速通道

函数 行为
iXlateTrivial 恒等(返回 iColor)
iXlateMonoInvert iColor ^ 1(黑白互换)
iXlateMonoTo0 / iXlateMonoTo1 全部映射为 0 / 1
iXlateToMono 查 1 项表:(iColor == pulXlate[0])
iXlateRGBToBW / iXlateRGBToWB 亮度阈值(r+g+b >= 383 判黑/白),仅用于纯黑/纯白目标

3.2 彩色→单色(点积判别)

c 复制代码
EXLATEOBJ_iXlateRGBToMono(pexlo, rgbColor)
{
    LONG lDist = r * pexlo->ToMono.lDeltaR +
                 g * pexlo->ToMono.lDeltaG +
                 b * pexlo->ToMono.lDeltaB;
    return (lDist > pexlo->ToMono.lHalfDist);
}

把前景/背景色看成 RGB 空间两点,预计算前景减背景的方向向量lDelta*)与判别阈值lHalfDist = (|F|²−|B|²)/2),每像素用点积符号判归属------几何意义即"像素点落在前背景连线哪一侧"。iXlateBGRToMono 仅是字节序反转版本(GetRValue 取蓝)。

3.3 位格式转换(16bpp 家族)

转换 要点
RGBtoBGR / 反向 仅交换 R/B 字节(`(v&0x00ff00ff)<<16
RGBto555 / BGRto555 24bpp → 5-5-5(右移+掩码,含 BGR 序)
RGBto565 / BGRto565 24bpp → 5-6-5
555toRGB / 555toBGR 5-5-5 → 24bpp,gajXlate5to8 扩位表(5bit→8bit 按 8 间隔扩展)
565toRGB / 565toBGR 5-6-5 → 24bpp,绿用 gajXlate6to8(6bit→8bit,4 间隔)
555to565 / 565to555 16bpp 互转(复制最高绿位等位操作)

扩位查表: gajXlate5to8[32] / gajXlate6to8[64] 把 5/6 位分量均匀映射到 8 位(如 5bit 值 v → v*255/31 取整),比移位+或操作精度更高。

3.4 位域转换

c 复制代码
EXLATEOBJ_iXlateShiftAndMask(pexlo, iColor)
{
    iNewColor  = _rotl(iColor, ulRedShift)   & ulRedMask;
    iNewColor |= _rotl(iColor, ulGreenShift) & ulGreenMask;
    iNewColor |= _rotl(iColor, ulBlueShift)  & ulBlueMask;
    return iNewColor;
}

通用位域重排:用循环左移对齐各通道后按掩码提取,源/目标的 555/565/掩码位域一律走此函数。

3.5 调色板索引转换

函数 行为
RGBtoPal / 555toPal / 565toPal 转 RGB 后 PALETTE_ulGetNearestPaletteIndex 求最近色索引
BitfieldsToPal 先 ShiftAndMask 转 RGB 再查最近索引
Table 通用查表:iColor >= cEntries ? 0 : pulXlate[iColor](越界保护)

4. EXLATEOBJ_vInitialize --- 转换器选择器

这是模块的总调度器 ,根据源/目标调色板类型(flFlags)组合,从 ~25 个函数中挑出最优实现:
#mermaid-svg-lerTbOjwFIwfCSnj{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-lerTbOjwFIwfCSnj .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-lerTbOjwFIwfCSnj .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-lerTbOjwFIwfCSnj .error-icon{fill:#552222;}#mermaid-svg-lerTbOjwFIwfCSnj .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-lerTbOjwFIwfCSnj .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-lerTbOjwFIwfCSnj .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-lerTbOjwFIwfCSnj .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-lerTbOjwFIwfCSnj .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-lerTbOjwFIwfCSnj .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-lerTbOjwFIwfCSnj .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-lerTbOjwFIwfCSnj .marker{fill:#333333;stroke:#333333;}#mermaid-svg-lerTbOjwFIwfCSnj .marker.cross{stroke:#333333;}#mermaid-svg-lerTbOjwFIwfCSnj svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-lerTbOjwFIwfCSnj p{margin:0;}#mermaid-svg-lerTbOjwFIwfCSnj .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-lerTbOjwFIwfCSnj .cluster-label text{fill:#333;}#mermaid-svg-lerTbOjwFIwfCSnj .cluster-label span{color:#333;}#mermaid-svg-lerTbOjwFIwfCSnj .cluster-label span p{background-color:transparent;}#mermaid-svg-lerTbOjwFIwfCSnj .label text,#mermaid-svg-lerTbOjwFIwfCSnj span{fill:#333;color:#333;}#mermaid-svg-lerTbOjwFIwfCSnj .node rect,#mermaid-svg-lerTbOjwFIwfCSnj .node circle,#mermaid-svg-lerTbOjwFIwfCSnj .node ellipse,#mermaid-svg-lerTbOjwFIwfCSnj .node polygon,#mermaid-svg-lerTbOjwFIwfCSnj .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-lerTbOjwFIwfCSnj .rough-node .label text,#mermaid-svg-lerTbOjwFIwfCSnj .node .label text,#mermaid-svg-lerTbOjwFIwfCSnj .image-shape .label,#mermaid-svg-lerTbOjwFIwfCSnj .icon-shape .label{text-anchor:middle;}#mermaid-svg-lerTbOjwFIwfCSnj .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-lerTbOjwFIwfCSnj .rough-node .label,#mermaid-svg-lerTbOjwFIwfCSnj .node .label,#mermaid-svg-lerTbOjwFIwfCSnj .image-shape .label,#mermaid-svg-lerTbOjwFIwfCSnj .icon-shape .label{text-align:center;}#mermaid-svg-lerTbOjwFIwfCSnj .node.clickable{cursor:pointer;}#mermaid-svg-lerTbOjwFIwfCSnj .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-lerTbOjwFIwfCSnj .arrowheadPath{fill:#333333;}#mermaid-svg-lerTbOjwFIwfCSnj .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-lerTbOjwFIwfCSnj .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-lerTbOjwFIwfCSnj .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-lerTbOjwFIwfCSnj .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-lerTbOjwFIwfCSnj .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-lerTbOjwFIwfCSnj .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-lerTbOjwFIwfCSnj .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-lerTbOjwFIwfCSnj .cluster text{fill:#333;}#mermaid-svg-lerTbOjwFIwfCSnj .cluster span{color:#333;}#mermaid-svg-lerTbOjwFIwfCSnj div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-lerTbOjwFIwfCSnj .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-lerTbOjwFIwfCSnj rect.text{fill:none;stroke-width:0;}#mermaid-svg-lerTbOjwFIwfCSnj .icon-shape,#mermaid-svg-lerTbOjwFIwfCSnj .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-lerTbOjwFIwfCSnj .icon-shape p,#mermaid-svg-lerTbOjwFIwfCSnj .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-lerTbOjwFIwfCSnj .icon-shape .label rect,#mermaid-svg-lerTbOjwFIwfCSnj .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-lerTbOjwFIwfCSnj .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-lerTbOjwFIwfCSnj .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-lerTbOjwFIwfCSnj :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是

MONO → MONO
MONO → 彩色
彩色 → MONO
INDEXED → INDEXED
RGB/BGR/555/565/BITFIELDS

→ 各目标
ShiftAndMask 且偏移全 0
pfnXlate == Trivial
EXLATEOBJ_vInitialize(ppalSrc, ppalDst,

crSrcBack, crDstBack, crDstFore)
默认 RGB; iUniq++ 递增; 清空状态
ppalDst == ppalSrc?
pfnXlate = Trivial, XO_TRIVIAL
非索引调色板 → 预计算

PALETTE_vGetBitMasks + CalculateShift
源/目标类型组合
4 情形: trivial / invert / to0 / to1
2 项查表 (DIB/直接 或 前背景色)
iXlateToMono + 点积常数

(CLR_INVALID 时 vInitRGBToMono)
建全量表; cDiff==0 → 退化 Trivial

(>6 项才堆分配)
按 5×5 组合表选专用函数
尾优化
退化 Trivial
XO_TRIVIAL

关键分支细节:

  1. MONO→MONO 四情形xlateobj.c(file:///d:/reactos/win32ss/gdi/eng/xlateobj.c#L541-L589)):先按"DIB/DDB 方向 + 前背景色"算出 iColors[0]/[1],再匹配 4 种简化:(0,1)→Trivial(1,0)→Invert(0,0)→To0(1,1)→To1
  2. 彩色→MONO 的 CLR_INVALID 特例 :调用方(如 NtGdiSetPixel)传 CLR_INVALID 表示"直接用 DIB 颜色表做点积判别",此时 EXLATEOBJ_vInitRGBToMono 用目标单色调色板的 0/1 号色初始化点积参数。
  3. INDEXED→INDEXED 退化优化 :构建全量表后若所有项 pulXlate[i]==i(恒等映射)则释放堆内存、退回 Trivial ;表 ≤6 项时直接复用联合池内嵌 aulXlate[6]>6EngAllocMemGDITAG_PXLATE)。
  4. 位域偏移预计算 CalculateShift:由源/目标掩码算旋转偏移,使运行时仅 _rotl + and

三个初始化包装:

函数 用途
EXLATEOBJ_vInitXlateFromDCs 由源/目标 DC 表面调色板初始化(BitBlt 用)
EXLATEOBJ_vInitXlateFromDCsEx 同前,但可指定源背景色(透明色/掩码 blt 用)
EXLATEOBJ_vInitSrcMonoXlate 强制源为单色调色板(gppalMono,单色源 blt 用)

EXLATEOBJ_vCleanuppulXlate 指向堆内存(≠内嵌 aulXlate)则 EngFreeMem 并复位。


5. DDI 公开函数与导出

函数 行为 win32k 导出 UMPD(gdi32→win32u→umpdstubs)
XLATEOBJ_iXlate 转换入口 :空指针→原值;否则 pfnXlate(pexlo, iColor) 分发 ---(内部+UMPD) NtGdiXLATEOBJ_iXlateumpdstubs(file:///d:/reactos/win32ss/gdi/eng/umpdstubs.c#L718),桩)
XLATEOBJ_cGetPalette iPal(XO_* 编号)返回源/目标/DC 调色板颜色(pPalOut==NULL 时返回项数);校验 PAL_INDEXED/PAL_BITFIELDS 匹配 ✓(win32k.spec(file:///d:/reactos/win32ss/win32k.spec#L228)) NtGdiXLATEOBJ_cGetPalette(桩)
XLATEOBJ_hGetColorTransform 返回 ICM 颜色变换句柄 ✓(L229) NtGdiXLATEOBJ_hGetColorTransform(桩)
XLATEOBJ_piVector 源为索引色时返回转换表指针,否则 NULL ✓(L231) ---

注意: XLATEOBJ_iXlate 在 xlateobj.c 中定义前先 #undef XLATEOBJ_iXlate(防御早期 winddi.h 曾把它定义成宏);内核态驱动直接调用,用户态 UMPD 经 NtGdiXLATEOBJ_iXlate


6. 消费方与调用链(核心活跃证据)

复制代码
ntgdi/bitblt.c  IntGdiBitBlt    → EXLATEOBJ_vInitXlateFromDCs
                                  → XLATEOBJ_iXlate(每像素)
    ↓ BLTINFO.XlateSourceToDest
DIB 引擎 (dib1bpp~dib32bpp, stretchblt, alphablend)
    内联宏: XLATEOBJ_iXlate(ColorTranslation, Source)   ← 每像素调用

eng/bitblt.c   画刷颜色 → XLATEOBJ_iXlate(pxloBrush, iSolidColor)
               前/背景色 → pxloRGB2Dest
ntgdi/freetype.c 文本 → exloRGB2Dst / exloDst2RGB (字形掩码与画刷)
ntgdi/fillshap.c  椭圆/洪水填充 → 目标色转换
ntgdi/dcutil.c   GetPixel/SetPixel → gpalRGB → 表面调色板
ntgdi/palette.c  GetNearestColor → EXLATEOBJ_vInitialize + iXlate
ntgdi/dibobj.c   DIB 位图/调色板互转
dib/alphablend.c  Alpha 混合 → 3 个 exlo 来回转换
c 复制代码
/* DIB 引擎内联转换宏(dib.h),所有位深 BitBlt 的像素必经之路 */
#define XLATEOBJ_iXlate(ColorTranslation, Source)  \
    ((ColorTranslation) ? \
        XLATEOBJ_pfnXlate(ColorTranslation)((ColorTranslation), (Source)) : (Source))

性能设计: 转换以函数指针单跳实现(无分支判断);Trivial 情形(最普遍,如 32bpp→32bpp 同格式)退化为直接返回原值,DIB 引擎甚至可走无转换快路径。


7. 与《分析_4》标注对照

标注 核对
《_4》第 39 行:xlateobj.c/h =「颜色转换对象」 准确。补充:核心活跃模块(非预留层);由 EXLATEOBJ.pfnXlate 函数指针分发 ~25 个专用转换函数,EXLATEOBJ_vInitialize 按调色板类型选择实现

8. 源码索引

文件 关键内容
xlateobj.c(file:///d:/reactos/win32ss/gdi/eng/xlateobj.c) 转换函数族、EXLATEOBJ_vInitialize/vInitXlateFromDCs(Ex)/vInitSrcMonoXlate/vCleanup、XLATEOBJ_iXlate/cGetPalette/hGetColorTransform/piVector
xlateobj.h(file:///d:/reactos/win32ss/gdi/eng/xlateobj.h) EXLATEOBJ 结构(联合池)、PFN_XLATE、初始化声明
winddi.h(file:///d:/reactos/sdk/include/psdk/winddi.h) XLATEOBJ 结构、XO_* 标志、ENGAPI 声明
palette.h(file:///d:/reactos/win32ss/gdi/ntgdi/palette.h) PAL_* 标志、CalculateShift、gpalRGB 等全局
palette.c(file:///d:/reactos/win32ss/gdi/ntgdi/palette.c) 调色板对象、全局调色板初始化
dib.h(file:///d:/reactos/win32ss/gdi/dib/dib.h) XLATEOBJ_iXlate 内联宏(BLTINFO 中调用)
bitblt.c(file:///d:/reactos/win32ss/gdi/eng/bitblt.c) 画刷/前景背景色转换消费
ntgdi/bitblt.c(file:///d:/reactos/win32ss/gdi/ntgdi/bitblt.c) IntGdiBitBlt 初始化 exlo
umpdstubs.c(file:///d:/reactos/win32ss/gdi/eng/umpdstubs.c#L705-L740) NtGdiXLATEOBJ_*(UMPD 桩)

关联模块:

  • 上层调用者:ntgdi/(file:///d:/reactos/win32ss/gdi/ntgdi/bitblt.c)(BitBlt/GetPixel/填充/文本)
  • 后端消费:gdi/dib/(file:///d:/reactos/win32ss/gdi/dib/)(各位深 BitBlt 内联转换)
  • 调色板来源:ntgdi/palette.c(file:///d:/reactos/win32ss/gdi/ntgdi/palette.c)
  • 兄弟对象:BRUSHOBJ/CLIPOBJ/SURFOBJ(同属 DDI 对象族)

本文档基于 ReactOS 源代码 win32ss/gdi/eng/xlateobj.c/h 及关联模块分析(2026 年 8 月)

相关推荐
mqiqe2 小时前
AgentScope Java Harness:4. 双层记忆系统 让 Agent 拥有真正的“长期大脑“
java·开发语言
gugucoding2 小时前
46. 【Java】JUC并发工具:让并发更简单
java·开发语言
Nebula_g3 小时前
JavaSE基础语法:面向对象高级(代码中的成分)
java·开发语言·编程·javase·技术栈·高级语法
for_ever_love__3 小时前
python基础语法学习: 异常的传递性
开发语言·python·学习
依然鸣4 小时前
PTA团体程序设计天梯赛L1真题讲解L1-077-080
开发语言·c++·算法·深度优先·pat考试·图论
byxdaz4 小时前
QT中服务使用
开发语言·qt
库玛西5 小时前
现代 C++ 智能指针全景指南:从 RAII 思想到工业级实践
c语言·开发语言·c++·笔记·面试
AC赳赳老秦6 小时前
风控岗应用:OpenClaw 采集公开司法与经营异常数据,自动生成企业风险评估报告
大数据·c语言·数据库·人工智能·python·php·openclaw
liulilittle6 小时前
无锁并发容器的设计与实现原理
开发语言·c++·set·map·并发·无锁·lock-free