Skip to content

Commit 66bd807

Browse files
shimatclaude
andcommitted
Fix IL3000 trimming warning in WindowsLibraryLoader (#1766)
Replace Assembly.Location with AppContext.BaseDirectory. Assembly.Location returns an empty string in single-file and AoT published apps, triggering IL3000 trimming warnings. AppContext.BaseDirectory is the correct alternative and is available across all current target frameworks (netstandard2.0, netstandard2.1, net8.0). The previous code already fell back to AppContext.BaseDirectory on the very next attempt, so the Assembly.Location lookup was also redundant. Remove the now-dead #if !NET40 guard (NET40 is never defined in this project; the minimum consumable framework via netstandard2.0 is .NET 4.6.1, where AppContext.BaseDirectory is available unconditionally). Remove the no-longer-needed `using System.Reflection` import. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 9a49884 commit 66bd807

3 files changed

Lines changed: 126 additions & 10 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# Personal notes (not for version control)
2+
docs/issue-backlog-ja.md
3+
14
# Build Folders (you can keep bin if you'd like, to store dlls and pdbs)
25
[Bb]in/
36
[Oo]bj/

docs/issue-backlog.md

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# Issue Backlog
2+
3+
> Last updated: 2026-05-30
4+
> Scope: issues closed as stale that appear actionable, plus open issues under investigation.
5+
6+
Check off items as they are resolved.
7+
8+
---
9+
10+
## ✅ Quick wins (small, self-contained fixes)
11+
12+
### [ ] #1766 — IL3000 warning with PublishTrimmed / PublishAoT
13+
14+
- **State**: closed (stale)
15+
- **URL**: https://github.com/shimat/opencvsharp/issues/1766
16+
- **Root cause**: `WindowsLibraryLoader.cs` uses `Assembly.Location`, which always returns an empty string in single-file / AoT apps, triggering the IL3000 trimming warning.
17+
- **Fix**: Replace `Assembly.Location` with `AppContext.BaseDirectory` (one-line change).
18+
- **Effort**: Low
19+
20+
---
21+
22+
### [ ] #1704 — Assembly version reported as `0.0.0.0`
23+
24+
- **State**: closed (stale)
25+
- **URL**: https://github.com/shimat/opencvsharp/issues/1704
26+
- **Root cause**: `AssemblyVersion` and `FileVersion` in the managed assemblies are not aligned with the NuGet package version, which breaks Windows Installer upgrade detection.
27+
- **Fix**: Set `<AssemblyVersion>` and `<FileVersion>` to `$(Version)` in `Directory.Build.props`.
28+
- **Effort**: Low
29+
30+
---
31+
32+
## 🔧 Medium effort
33+
34+
### [ ] #1765 — Native DLLs copied twice when targeting .NET Framework 4.8
35+
36+
- **State**: closed (stale)
37+
- **URL**: https://github.com/shimat/opencvsharp/issues/1765
38+
- **Root cause**: NuGet restore already copies the `runtimes/` DLLs to the output directory, but the package's custom `.targets` file copies them again into `dll/x64`, resulting in duplicates.
39+
- **Fix**: Add a condition to the custom copy task in the `.targets` file so it is skipped when NuGet has already handled the copy (i.e., on net48 targets).
40+
- **Effort**: Medium
41+
42+
---
43+
44+
### [ ] #1753`NativeMethods` static constructor fires too early
45+
46+
- **State**: closed (stale)
47+
- **URL**: https://github.com/shimat/opencvsharp/issues/1753
48+
- **Root cause**: `NativeMethods` calls `TryPInvoke` in its static constructor, which runs before user code has a chance to register a custom `NativeLibrary.SetDllImportResolver`. Custom native loaders therefore cannot intercept the first P/Invoke.
49+
- **Fix**: Switch to lazy initialization, or expose a public `Initialize()` method that users can call before any OpenCvSharp type is first referenced.
50+
- **Effort**: Medium
51+
52+
---
53+
54+
### [ ] #1731 — WASM runtime fails to publish under .NET 9 with trimming/linking enabled
55+
56+
- **State**: closed (stale)
57+
- **URL**: https://github.com/shimat/opencvsharp/issues/1731
58+
- **Root cause**: `OpenCvSharp4.runtime.wasm` ships `OpenCvSharpExtern.a` compiled with Emscripten 3.1.32 (.NET 8 era). .NET 9 uses Emscripten 3.1.56, whose C++ stdlib ABI differs, causing `undefined symbol` linker errors.
59+
- **Fix**: Rebuild `OpenCvSharpExtern.a` with Emscripten 3.1.56 and publish a `net9.0`-targeting package. Add a .NET 9 + Emscripten 3.1.56 build step to `.github/workflows/wasm.yml`.
60+
- **Effort**: Medium
61+
62+
---
63+
64+
## 🏗️ Large effort
65+
66+
### [ ] #1743 — No NuGet runtime package for Windows ARM64
67+
68+
- **State**: closed (stale)
69+
- **URL**: https://github.com/shimat/opencvsharp/issues/1743
70+
- **Note**: A community fork (`xavave/opencvsharp.win.arm64`) has already done this work and can serve as a reference.
71+
- **Fix**: Build `OpenCvSharpExtern.dll` for ARM64 Windows, package it under `runtimes/win-arm64/native/`, and add an ARM64 Windows CI build.
72+
- **Effort**: Large
73+
74+
---
75+
76+
### [ ] #1737 — Camera calibration with `CharucoBoard` not supported
77+
78+
- **State**: closed (stale)
79+
- **URL**: https://github.com/shimat/opencvsharp/issues/1737
80+
- **Note**: A community fork (`xavave`) has implemented this and can serve as a reference.
81+
- **Fix**: Add wrappers for `CharucoBoard` and the `Cv2.Aruco.CalibrateCamera` overloads in the aruco module.
82+
- **Effort**: Large
83+
84+
---
85+
86+
## ⏸️ On hold (need more information)
87+
88+
### #1774 — Suspected memory leak in `CvtColor BGR2RGBA`
89+
90+
- **State**: closed (stale)
91+
- **URL**: https://github.com/shimat/opencvsharp/issues/1774
92+
- **Note**: Cannot confirm this is a wrapper bug without a verified minimal repro showing native heap growth (e.g. via a native heap profiler). Revisit if a clean repro is provided.
93+
94+
### #1748`libssl.lib` linked in `OpenCvSharpExtern.vcxproj`
95+
96+
- **State**: closed (stale)
97+
- **URL**: https://github.com/shimat/opencvsharp/issues/1748
98+
- **Note**: Unclear whether this is a stale leftover or a genuine dependency. Needs inspection of the `.vcxproj` linker settings.
99+
100+
### #1745 — Intermittent `AccessViolationException` in `CLAHE.Apply`
101+
102+
- **State**: closed (stale)
103+
- **URL**: https://github.com/shimat/opencvsharp/issues/1745
104+
- **Note**: Occurs roughly once every few days. Hard to attribute to the wrapper layer without a repro. Likely a race condition or memory corruption in native OpenCV. Revisit if a repro is found.
105+
106+
---
107+
108+
## 📋 Open issues under investigation
109+
110+
### #1863 — Crash in `BarcodeDetector` (0xc0000409)
111+
112+
- **State**: open
113+
- **URL**: https://github.com/shimat/opencvsharp/issues/1863
114+
- **Note**: Cannot reproduce with our own tests. Waiting for a stack trace and full environment details from the reporter.
115+
116+
### #1789`ConcatLayer` throws "Inconsistent shape"
117+
118+
- **State**: open
119+
- **URL**: https://github.com/shimat/opencvsharp/issues/1789
120+
- **Note**: Reportedly fixed in OpenCV 4.10, but the reporter sees it on 4.11. Likely an ONNX export configuration issue. Cannot investigate without the model file.

src/OpenCvSharp/Internal/PInvoke/WindowsLibraryLoader.cs

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System.Diagnostics;
22
using System.Globalization;
3-
using System.Reflection;
43
using System.Runtime.InteropServices;
54
using System.Text;
65

@@ -136,19 +135,13 @@ public void LoadLibrary(string dllName, IEnumerable<string>? additionalPaths = n
136135
if (dllHandle != IntPtr.Zero) return;
137136
}
138137

139-
// Try loading from executing assembly domain
140-
var executingAssembly = GetType().GetTypeInfo().Assembly;
141-
var baseDirectory = Path.GetDirectoryName(executingAssembly.Location) ?? "";
142-
dllHandle = LoadLibraryInternal(dllName, baseDirectory, processArch);
143-
if (dllHandle != IntPtr.Zero) return;
144-
145138
// Gets the pathname of the base directory that the assembly resolver uses to probe for assemblies.
139+
// AppContext.BaseDirectory is preferred over Assembly.Location because the latter returns an empty
140+
// string in single-file / AoT published apps and triggers IL3000 trimming warnings.
146141
// https://github.com/dotnet/corefx/issues/2221
147-
#if !NET40
148-
baseDirectory = AppContext.BaseDirectory;
142+
var baseDirectory = AppContext.BaseDirectory;
149143
dllHandle = LoadLibraryInternal(dllName, baseDirectory, processArch);
150144
if (dllHandle != IntPtr.Zero) return;
151-
#endif
152145

153146
// Finally try the working directory
154147
baseDirectory = Path.GetFullPath(Directory.GetCurrentDirectory());

0 commit comments

Comments
 (0)