Skip to content

optional_library: Prefer explicit locations over ambient search - #180

Merged
ethindp merged 1 commit into
ethindp:masterfrom
qt06:optional-library-search-order
Nov 8, 2026
Merged

ethindp merged 1 commit into
ethindp:masterfrom
qt06:optional-library-search-order

Conversation

@qt06

@qt06 qt06 commented Nov 7, 2026 •

Copy link
Copy Markdown
Contributor

open_optional_library previously called LoadLibrary by bare DLL name first. Windows could resolve an unrelated same-named copy from the working directory or %PATH%, and Prism would not then try the product's registered install directory. A stale DLL with a different export set could therefore make a backend unavailable even though its registered installation contained a usable DLL.

Search the directory containing Prism first, then the install directory from the registry when provided, and only then fall back to Windows' ambient DLL search path. App-local deployments remain supported. The helper is shared by optional-library backends, so the behavior applies to all of them; the registry path is only used by backends that provide one.

Update the backend contribution guidance to document the order and distinguish required exports from optional exports.

Verified with x64 and x86 Windows builds, clang-tidy, and a stale-DLL-in-%PATH% test: the registered ZDSR installation was selected instead of the older DLL.

Related ZDSR follow-ups: #181 makes the Braille export optional, and #182 documents the ZDSR behavior introduced by #177 and #178. This loader change is independently useful and does not depend on those PRs.

The bare-name LoadLibrary call could resolve an unrelated older DLL from
the working directory or PATH before Prism checked the product's
registered install directory. If that DLL had a different export set,
the backend could be rejected even though the registered installation
contained a usable library.

Search next to Prism first, then the explicitly registered product
directory, and use Windows' ambient DLL search path only as a fallback.
Keep the app-local override and document the order and optional-export
contract for backend authors.

Signed-off-by: qt06 <qt06.com@gmail.com>
@ethindp
ethindp merged commit 8f19365 into ethindp:master Nov 8, 2026
86 checks passed
ethindp pushed a commit that referenced this pull request Nov 9, 2026
Some ZDSR API versions export the four speech functions (`InitTTS`,
`Speak`, `GetSpeakState`, `StopSpeak`) but do not provide `Braille`.
Requiring the Braille export prevented those versions from loading even
though speech was available.

Bind `Braille` independently from the required speech functions. The
backend advertises `SUPPORTS_BRAILLE` only after initialization confirms
the export; without it, direct Braille calls return
`PRISM_ERROR_NOT_IMPLEMENTED`, while `output` continues with speech
only. `get_features` no longer loads the DLL and only reports Braille
support after initialization.

Verified with an app-local test DLL exporting the four speech functions
but no `Braille`: initialization succeeds, Braille is not advertised,
direct Braille returns not-implemented, and speech-only output succeeds.
With the installed API that exports Braille, `get_features` omits the
feature before initialization and reports it after successful
initialization. x64 and x86 builds pass, and clang-tidy reports no
diagnostics for `zdsr.cpp`.

Related PRs: #180 fixes optional DLL search precedence; #182 documents
the ZDSR-specific Braille behavior together with the independent-channel
readiness and process-probe behavior from #177 and #178.

Signed-off-by: qt06 <qt06.com@gmail.com>
ethindp pushed a commit that referenced this pull request Nov 9, 2026
Update the ZDSR backend notes to reflect the merged behavior:

- Runtime support requires both `ZDSRMain.exe` and `ZDSRDaemon.exe`;
service and per-channel processes are not used as the availability
signal.
- With `ZDSRAPI.ini` selecting an independent channel (`type=1`), the
channel may still be starting after `InitTTS` succeeds. Status 9 is
treated as not speaking, so initialization succeeds and `is_speaking`
returns false. `speak` returns `PRISM_ERROR_BACKEND_NOT_AVAILABLE` until
the channel is ready; callers may retry without reinitializing.
- Older ZDSRAPI versions may not export `Braille`. After initialization,
the backend advertises Braille support only when the loaded API provides
that export; otherwise direct Braille calls return
`PRISM_ERROR_NOT_IMPLEMENTED` and `output` uses speech only.

Documentation-only change. The runtime-probe and channel-readiness
behavior was introduced by #177 and #178; the optional Braille behavior
is implemented by #181.

Related PRs: #180 fixes optional DLL search precedence; #181 makes the
ZDSR Braille export optional.

Signed-off-by: qt06 <qt06.com@gmail.com>
@qt06
qt06 deleted the optional-library-search-order branch November 9, 2026 06:16
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.

2 participants