Skip to content

Remove TryPInvoke() from NativeMethods static constructor to allow custom native library loading - #1887

Merged
shimat merged 7 commits into
mainfrom
fix/1753-native-methods-init
May 30, 2026
Merged

shimat merged 7 commits into
mainfrom
fix/1753-native-methods-init

Conversation

@shimat

@shimat shimat commented May 30, 2026 •

Copy link
Copy Markdown
Owner

Fixes #1753

Problem

NativeMethods.TryPInvoke() was called automatically in the static constructor. The static constructor fires on the first access to any NativeMethods member, leaving no window for user code to register a NativeLibrary.SetDllImportResolver or any other custom native loading mechanism before the first P/Invoke call.

Change

Remove the TryPInvoke() call from the static constructor. The method remains public for callers who want explicit pre-flight validation.

The recommended pattern for users who need custom native loading is now:

    // 1. Register your resolver before any OpenCvSharp use.
    //    typeof(NativeMethods) does not trigger the static constructor,
    //    so this is safe to call first.
    NativeLibrary.SetDllImportResolver(typeof(NativeMethods).Assembly, (name, assembly, path) =>
    {
        // custom loading logic
    });

    // 2. Optionally validate that the native library loads correctly.
    NativeMethods.TryPInvoke();

    // 3. Use OpenCvSharp normally.
    using var mat = new Mat(...);

The static constructor now only calls LoadLibraries(), which on .NET 5+ is a no-op unless WindowsLibraryLoader.Instance.AdditionalPaths has entries.

Note on TryPInvoke()

TryPInvoke() catches DllNotFoundException / BadImageFormatException and rethrows them as a more descriptive OpenCvSharpException. It is no longer called automatically but remains available as an explicit opt-in for pre-flight validation. It is not strictly required — the first actual OpenCvSharp API call will fail naturally if the native library is missing.

Summary by CodeRabbit

  • Documentation

    • Added repository structure overview, versioning/release rules, Windows native DLL loading guidance, updated issue backlog guidance, and clarified UTF‑8 BOM handling and file-creation workflow in contributor instructions.
  • Behavior Change

    • Native library pre‑flight validation no longer runs automatically during initialization; explicit validation must be invoked after configuring custom native library loading.

Review Change Stack

shimat and others added 3 commits May 30, 2026 21:09
TryPInvoke() was called automatically in the NativeMethods static
constructor, making it impossible to register a NativeLibrary.SetDllImportResolver
(or any other custom native loading mechanism) before the first P/Invoke
call. The static constructor fires on the first access to any NativeMethods
member, leaving no window for user setup code.

Remove the automatic TryPInvoke() call. The method remains public for
callers who want explicit pre-flight validation — call it after setting
up custom native library loading, before making any other OpenCvSharp API
calls. The static constructor now only calls LoadLibraries(), which on
.NET 5+ is a no-op unless AdditionalPaths are set.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add an explicit warning that AI assistants frequently forget to apply
UTF-8 BOM on newly created files, with concrete examples of affected
paths. Simplify the BOM conversion snippet to a one-liner.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@shimat shimat self-assigned this May 30, 2026
@coderabbitai

coderabbitai Bot commented May 30, 2026 •

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: fc9b773a-3857-4431-b120-a0d9bc51b217

📥 Commits

Reviewing files that changed from the base of the PR and between 1a19cb8 and 9d4ab58.

📒 Files selected for processing (5)
  • .devcontainer/manylinux/devcontainer.json
  • .github/copilot-instructions.md
  • docs/issue-backlog.md
  • docs/release-process.md
  • src/Directory.Build.props
✅ Files skipped from review due to trivial changes (2)
  • .devcontainer/manylinux/devcontainer.json
  • src/Directory.Build.props
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/copilot-instructions.md

📝 Walkthrough

Walkthrough

This PR removes automatic P/Invoke validation from NativeMethods static initialization to simplify custom native library loading, updates XML documentation to clarify explicit invocation requirements, marks the related issue as resolved, and expands repository developer guidance covering BOM handling, structure, versioning rules, and issue backlog maintenance.

Changes

NativeMethods initialization behavior and repository guidance

Layer / File(s) Summary
NativeMethods initialization behavior
src/OpenCvSharp/Internal/PInvoke/NativeMethods/NativeMethods.cs, docs/issue-backlog.md
NativeMethods static constructor no longer calls TryPInvoke() automatically; TryPInvoke() XML documentation clarifies it must be invoked explicitly after custom native library loading is configured; issue #1753 is marked resolved.
Developer guidance and Copilot instructions
.github/copilot-instructions.md, .devcontainer/manylinux/devcontainer.json, docs/issue-backlog.md, docs/release-process.md, src/Directory.Build.props
BOM handling instructions updated with explicit warning about AI assistants omitting BOM, Write/create_file behavior noted, an immediate PowerShell conversion step added, BOM verification snippet revised, Linux no-BOM exceptions narrowed (removed devcontainer.json/.devcontainer/*), and several files now include a leading BOM marker where applicable; repository structure, versioning/release rules, Windows native DLL loading notes, and issue backlog linkage were added/adjusted.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and specifically summarizes the main change: removing TryPInvoke() from NativeMethods static constructor and the key benefit of enabling custom native library loading.
Linked Issues check ✅ Passed The PR addresses all coding requirements from #1753: removes automatic TryPInvoke() call from static constructor, keeps TryPInvoke() public for optional explicit validation, and enables consumers to register custom resolvers before first P/Invoke.
Out of Scope Changes check ✅ Passed All changes are scoped to #1753 and its objectives. Documentation updates, BOM encoding adjustments, and version-related docs align with supporting the core fix and establishing related practices.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/1753-native-methods-init

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
docs/issue-backlog.md (1)

45-50: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update #1753 “Fix” text to match the implemented resolution.

The item is marked resolved, but the fix description still suggests alternatives that were not applied. Please update it to reflect the actual change (removing automatic TryPInvoke() from the static constructor and making it explicit/optional).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/issue-backlog.md` around lines 45 - 50, Update the fix description to
reflect the implemented change: remove the suggestion to switch to lazy
initialization or expose Initialize(), and state that automatic TryPInvoke()
call was removed from NativeMethods' static constructor and made
explicit/optional (e.g., users must call NativeMethods.Initialize() or the new
explicit initialization API) so custom NativeLibrary.SetDllImportResolver can
run first; reference the NativeMethods type, its static constructor, and
TryPInvoke() when editing the text.
.github/copilot-instructions.md (1)

9-14: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Remove the devcontainer.json BOM exception to avoid conflicting encoding policy.

This block says devcontainer.json must be saved without BOM, but repository coding policy requires BOM for .json files. Please align this section so contributors don’t receive contradictory instructions.

As per coding guidelines "**/*.{cs,csproj,yml,yaml,md,json,xaml,xml,txt}: All source files must be saved as UTF-8 with BOM (EF BB BF)."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/copilot-instructions.md around lines 9 - 14, Update
.github/copilot-instructions.md to remove the conflicting exception for
"devcontainer.json": keep Dockerfile and shell script entries as BOM-exempt, but
delete "devcontainer.json" from the list and clarify that only files under
".devcontainer/" (if any tooling requires it) are processed without BOM or,
preferably, remove ".devcontainer/" too so JSON files follow the repo-wide UTF-8
with BOM policy; ensure the text references "devcontainer.json" and
".devcontainer/" so reviewers can locate and validate the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In @.github/copilot-instructions.md:
- Around line 9-14: Update .github/copilot-instructions.md to remove the
conflicting exception for "devcontainer.json": keep Dockerfile and shell script
entries as BOM-exempt, but delete "devcontainer.json" from the list and clarify
that only files under ".devcontainer/" (if any tooling requires it) are
processed without BOM or, preferably, remove ".devcontainer/" too so JSON files
follow the repo-wide UTF-8 with BOM policy; ensure the text references
"devcontainer.json" and ".devcontainer/" so reviewers can locate and validate
the change.

In `@docs/issue-backlog.md`:
- Around line 45-50: Update the fix description to reflect the implemented
change: remove the suggestion to switch to lazy initialization or expose
Initialize(), and state that automatic TryPInvoke() call was removed from
NativeMethods' static constructor and made explicit/optional (e.g., users must
call NativeMethods.Initialize() or the new explicit initialization API) so
custom NativeLibrary.SetDllImportResolver can run first; reference the
NativeMethods type, its static constructor, and TryPInvoke() when editing the
text.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0d63c3bb-be9c-4997-af36-250d12193859

📥 Commits

Reviewing files that changed from the base of the PR and between ab62a9d and 7a51385.

📒 Files selected for processing (3)
  • .github/copilot-instructions.md
  • docs/issue-backlog.md
  • src/OpenCvSharp/Internal/PInvoke/NativeMethods/NativeMethods.cs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/issue-backlog.md`:
- Line 50: The docs/issue-backlog.md file is missing a UTF-8 BOM; fix it by
rewriting the file using a UTF8 encoding that emits a BOM (use
System.Text.UTF8Encoding with the "emit BOM" flag set) and write the existing
content back using System.IO.File.WriteAllText (or equivalent) so the file
starts with EF BB BF; locate docs/issue-backlog.md and perform the rewrite (read
raw content then write with the UTF8Encoding(true)) to ensure the BOM is
present.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 58f865dc-2741-417c-bce7-cca9fa656e21

📥 Commits

Reviewing files that changed from the base of the PR and between 1e071c2 and 1a19cb8.

📒 Files selected for processing (1)
  • docs/issue-backlog.md

Comment thread docs/issue-backlog.md
shimat and others added 2 commits May 30, 2026 21:55
devcontainer.json is parsed by VS Code which handles UTF-8 BOM in JSON
fine. Remove it (and the .devcontainer/ directory reference) from the
Linux-tooling BOM exception list so it follows the repo-wide UTF-8 with
BOM policy. Apply BOM to the existing .devcontainer/manylinux/devcontainer.json.

Dockerfile and shell scripts remain BOM-exempt as they are processed by
Linux tools that do not tolerate a BOM.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
docs/issue-backlog.md, docs/release-process.md, and src/Directory.Build.props
were created by the Write tool which does not add a BOM.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@shimat
shimat merged commit e6d3ad9 into main May 30, 2026
10 checks passed
@shimat
shimat deleted the fix/1753-native-methods-init branch May 30, 2026 13:13
@shimat shimat added the enhancement New feature or improvement to OpenCvSharp label Jul 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or improvement to OpenCvSharp

Projects

None yet

Development

Successfully merging this pull request may close these issues.

NativeMethods TryPInvoke makes it difficult to initialize the library

1 participant