Skip to content

Load pre-compiled NLP++ analyzers (engine 3.7.11 + ICU preload) - #37

Merged
ddehilster merged 1 commit into
VisualText:mainfrom
ddehilster:feat/load-compiled-analyzer-icu
Jul 14, 2026
Merged

ddehilster merged 1 commit into
VisualText:mainfrom
ddehilster:feat/load-compiled-analyzer-icu

Conversation

@ddehilster

Copy link
Copy Markdown
Member

What

Makes analyze(..., compiled=True) load and run a pre-compiled NLP++ analyzer (single combined DLL deploy) from a fresh engine and produce correct output.

Changes

  • nlp-engine submodule → v3.7.11 (82ff50e): combined analyzer+KB DLL; lazy-opens *-full.dict/*-full.kbb at runtime in compiled mode.
  • NLPPlus/__init__.py: _preload_icu() ctypes-loads every vendored icu*/msvcp* DLL by real name at import (dep order icudt → icuuc → icuin).
  • .github/workflows/publish.yml: repair wheels with delvewheel --no-mangle-all --add-dll icuin78.dll.

Root cause of [Couldn't load library: bin/kb.dll]

A compiled analyzer DLL imports icuin<ver>.dll + icuuc<ver>.dll by real name and is dlopened via a plain LoadLibrary(fullpath), whose dependency resolution only consults already-loaded modules (by base name), the DLL's own dir, or PATH — not os.add_dll_directory. Default delvewheel repair mangled the ICU names and never vendored icuin (the extension only imports icuuc/icudt), so the analyzer's ICU imports went unresolved. Keeping real names + force-vendoring icuin + preloading them by name fixes it.

Verification (Windows, cp313)

Fresh temp-dir engine, copy only compiled/TextGen, analyze(..., compiled=True): [Loaded compiled KB library], [Loaded compiled analyzer], all four en-*-full lazy files open, output.txt → Fee $715.00., verify.json produced. Interpreted path unchanged.

Note

Per-render data.kbb override (B=$999) is out of scope: in compiled mode the engine reads only lazy *-full files, and the sample compiled/TextGen bakes its dev data into the DLL — that belongs to the analyzer/deploy side.

🤖 Generated with Claude Code

Bump the nlp-engine submodule to v3.7.11 (82ff50e), which loads a compiled
analyzer/KB as a single combined DLL and lazy-opens *-full.dict/*-full.kbb at
runtime in compiled mode.

Fix the real reason analyze(..., compiled=True) failed with
"[Couldn't load library: bin/kb.dll]": a compiled analyzer DLL imports
icuin<ver>.dll + icuuc<ver>.dll by their real names and is dlopened by the
engine via a plain LoadLibrary(fullpath), whose dependency resolution only
consults already-loaded modules (by base name), the DLL's own dir, or PATH --
not os.add_dll_directory. delvewheel's default repair mangled the vendored ICU
names and never vendored icuin (our extension only imports icuuc/icudt), so the
analyzer's ICU imports went unresolved.

- NLPPlus/__init__.py: _preload_icu() ctypes-loads every vendored icu*/msvcp*
  DLL by real name at import (dep order icudt -> icuuc -> icuin) so a compiled
  analyzer binds them from memory.
- publish.yml: repair wheels with `delvewheel --no-mangle-all --add-dll
  icuin78.dll` so released wheels keep real ICU names and vendor icuin.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@ddehilster
ddehilster merged commit 699dd7a into VisualText:main Jul 14, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant