From e1a0fbf9c0dfb0a7573b5a2120c55119d09764f6 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Sat, 10 Oct 2026 20:57:26 +0800 Subject: [PATCH] =?UTF-8?q?fix(cdef):=20=E8=A3=B8=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E5=88=AB=E5=90=8D=E6=9E=84=E9=80=A0=E7=9A=84=20CDefine?= =?UTF-8?q?=EF=BC=88=E5=A6=82=20DWORD(-11)=EF=BC=89=E4=B9=9F=E8=83=BD?= =?UTF-8?q?=E6=8F=90=E5=8F=96=E8=BF=9B=20=5Fall=5Fdefine=5Fconstants?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 根因:ConstEvaluator 只认 t.X(...) / from t import X 的类型构造,裸 typedef 别名(DWORD(-11))既不在 _t_module 也不在 mock ctx 的 _t_type_symbols → eval_full 返回 None → _ExtractCDefineConstantsFromPyi 整条丢弃该常量。win32file.vp 的 STD_INPUT/OUTPUT/ERROR_HANDLE 是全仓唯一用别名构造写的 define,正对应链接期三个 undefined symbol(模块属性访问 wf.STD_*_HANDLE 解析落空后退化成未定义全局)。补:eval_full 失败且值为单参 Call 时,回退求值其实参(CDefine 只要常量值,位型一致)。 --- lib/Projectrans/Phase2Translator.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/Projectrans/Phase2Translator.py b/lib/Projectrans/Phase2Translator.py index 94197e4..5a29087 100644 --- a/lib/Projectrans/Phase2Translator.py +++ b/lib/Projectrans/Phase2Translator.py @@ -620,6 +620,16 @@ def _ExtractCDefineConstantsFromPyi(pyi_path: str, all_dc: dict[str, object]) -> if isinstance(node, ast.AnnAssign) and isinstance(node.target, ast.Name): if AnnotationContainsName(node.annotation, 'CDefine') and node.value: val: object = ConstEvaluator.eval_full(node.value, ctx) + if val is None and isinstance(node.value, ast.Call) and len(node.value.args) == 1: + # 类型构造的**裸别名**形态(如 `DWORD(-11)`,非 `t.CUnsignedLong(-11)`): + # eval_full 只认 `t.X(...)` / `from t import X`(见 ConstEvaluator + # _eval_compile_time_call),裸 typedef 别名既不在 _t_module 也不在 + # mock ctx 的 _t_type_symbols 里 → 返回 None → 该常量被整条丢弃。 + # 现场:win32file.vp 的 STD_INPUT/OUTPUT/ERROR_HANDLE 是全仓**唯一**用 + # 别名构造写的 define → 唯独这三个进不了 _all_define_constants,导致 + # 模块属性访问 `wf.STD_ERROR_HANDLE` 解析落空、退化成未定义的全局符号 + # (链接失败)。CDefine 关心的是常量值,故回退求值其唯一实参(位型一致)。 + val = ConstEvaluator.eval_full(node.value.args[0], ctx) if val is not None and isinstance(val, (int, float, str)): all_dc[node.target.id] = val except Exception as e: