shimat / opencvsharp

OpenCV wrapper for .NET
Apache License 2.0
5.39k stars 1.15k forks source link

Unable to load DLL 'OpenCvSharpExtern' in 4.2.0 #818

Closed mpolicki closed 4 years ago

mpolicki commented 4 years ago

Summary of your issue

System.DllNotFoundException: Unable to load DLL 'OpenCvSharpExtern': The specified module could not be found. (Exception from HRESULT: 0x8007007E)

Environment

Windows 10 1903 18362.535 64-bit VS 2019 16.4.2 Target .NET Framework 4.7.2 OpenCvSharp4.Windows 4.2.0.20191223

What did you do when you faced the problem?

Created a new solution (class library), ran a test for the code below.

Example code:

    public class Class42
    {
        public Class42()
        {
            new Mat();
        }
    }

Output:

System.TypeInitializationException: The type initializer for 'OpenCvSharp.Mat' threw an exception. ---> System.TypeInitializationException: The type initializer for 'OpenCvSharp.NativeMethods' threw an exception. ---> System.DllNotFoundException: Unable to load DLL 'OpenCvSharpExtern': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
  Stack Trace: 
    NativeMethods.redirectError(CvErrorCallback errCallback, IntPtr userdata, IntPtr& prevUserdata)
    NativeMethods.LoadLibraries(IEnumerable`1 additionalPaths) line 79
    NativeMethods.cctor() line 40
    --- End of inner exception stack trace ---
    NativeMethods.core_Mat_sizeof()
    Mat.cctor() line 714
    --- End of inner exception stack trace ---
    Mat.ctor()

What did you intend to be?

No exception.

The exact same setup works with OpenCvSharp4.Windows 4.1.1.20191216. Also, OpenCvSharpExtern.dll files are present in both [project]\bin\Debug\dll\x86 and [project]\bin\Debug\dll\x64. I opened them in Dependencies and didn't see any errors; don't know what to look for beyond that.

shimat commented 4 years ago

:thinking: Well... it may work if you delete the bin/ folder and try again.

I also tried, but it worked. This is a VS solution I made for testing the issue. OpenCvSharpClassLibraryTest.zip

mpolicki commented 4 years ago

I tried deleting the bin folder; that didn't help.

I then tried the solution you posted. After I built and ran it, I got the same exception (console app and test projects). Then I noticed that there wasn't a dll folder in Release for the console app, so I did a Clean and Rebuild. That did create a dll folder in Release with the appropriate content. However, running the console app again resulted in the exception again.

Finally, I ran Process Monitor set to show file system activity for ConsoleApp1.exe and ran the console app. Inspecting the output revealed that shortly after the app successfully opens OpenCvSharpClassLibraryTest\ConsoleApp1\bin\Release\dll\x86\OpenCvSharpExtern.dll, it tries to open OpenCvSharpClassLibraryTest\ConsoleApp1\bin\Release\OpenCvSharpExtern.DLL and fails. I assume this is the point where the exception is caused.

Do you have any idea why it would try to find the dll in the base folder instead of in the dll \... folder?

shimat commented 4 years ago

Inspecting the output revealed that shortly after the app successfully opens OpenCvSharpClassLibraryTest\ConsoleApp1\bin\Release\dll\x86\OpenCvSharpExtern.dll

x86??? Your environment is x64, but the x86 DLL is loaded...

OpenCvSharp controls the target DLL file path for C# DllImport by loading the dll/[x64 or x86]/OpenCvSharpExtern.dll in advance with the Win32API LoadLibrary function. If the platform setting is AnyCPU, the program must determine whether the native DLL to be loaded at runtime should be x64 or x86.

As a workaround, manually copying dll/x64/OpenCvSharpExtern.dll to the same folder as the exe file may make the program work. copy dll/x64/OpenCvSharpExtern.dll ..\..\

mpolicki commented 4 years ago

I've checked in Task Manager, and the console app is 32-bit. According to this, the reason is that "Prefer 32-bit" is checked in the project properties.

Copying the 64-bit dll to the exe folder causes the program to crash with a System.BadImageFormatException (as might be expected). Copying the 32-bit dll to the exe folder results in a new exception: System.DllNotFoundException: Unable to load DLL 'OpenCvSharpExtern': A dynamic link library (DLL) initialization routine failed. (Exception from HRESULT: 0x8007045A).

After I unchecked "Prefer 32-bit" and rebuilt the solution, the console app showed as 64-bit in Task Manager. Without copying any dlls, running it caused the original exception. After I copied the 64-bit dll to the exe folder, I got the "initialization routine failed" exception again.

I'm guessing there's something different about OpenCvSharpExtern.dll between 4.1.1.20191216 and 4.2.0.20191223 that's causing this, but I can't figure out what.

mpolicki commented 4 years ago

I've used Debug Diag to analyze the crash, and it reports that

the assembly instruction at OpenCvSharpExtern!xphoto_oilPainting2+c65836 in E:\Projects\OpenCvSharpClassLibraryTest\ConsoleApp1\bin\Release\dll\x64\OpenCvSharpExtern.dll has caused an unknown exception (0xc000001d) on thread 0

shimat commented 4 years ago

Thank you. xphoto_oilPainting2 ?? I can't find any problems there, but in the next version I will try to disable it for now. https://github.com/shimat/opencvsharp/blob/master/src/OpenCvSharpExtern/xphoto.h#L308

mpolicki commented 4 years ago

No problem. I've enabled native code debugging in the project properties for the console app, caught the exception and looked at the disassembly at the point where the exception was thrown (which, in hindsight, I should have done immediately). It turns out exception 0xC000001D means Illegal Instruction, and the instruction in question is vpxor, which, according to Intel 64 and IA-32 Architectures Software Developer’s Manual, is an AVX/AVX2 instruction (and my CPU does not support AVX).

I suppose the question now is why does DLL initialization code need to run AVX instructions, and why doesn't it check for CPU support before trying to run them?

Also, 0xc65836 is a 12MB offset, so the problem might not actually be in xphoto_oilPainting2. If I had a debug build of OpenCvSharpExtern.dll and its PDB file, I might be able to see which function contains the offending code.

bbday commented 4 years ago

Yes i have same issue with some pc that have old cpu pentium N that cant load OpenCvSharpExtern i try to use geterror and return me 1114 = ERROR_DLL_INIT_FAILED, new cpu dont have issue with same code

mpolicki commented 4 years ago

I've tried building the project (commit tagged 4.2.0.20191223) to get a debug build of OpenCvSharpExtern.dll, but I have not succeeded. First, VS complained about a missing opencv_world420d.lib file, so I got the one from opencv-4.2.0-vc14_vc15.exe here and put it in opencv_files_420\win-x64\x64\vc16\staticlib. After that, when I tried building an x64 Debug build, I got 149 unresolved external symbol errors for various functions for OpenCvSharpExtern.

shimat commented 4 years ago

I'm sorry but the project settings of the Debug configuration is incomplete, as I always use the Release configuration.

opencv-4.2.0-vc14_vc15.exe does not include opencv_contrib, so you need to build OpenCV(with contrib) yourself in order to build OpenCvSharpExtern.

shimat commented 4 years ago

My cmake log of building OpenCV

  CPU/HW features:
    Baseline:                    SSE SSE2 SSE3
      requested:                 SSE3
    Dispatched code generation:  SSE4_1 SSE4_2 FP16 AVX AVX2 AVX512_SKX
      requested:                 SSE4_1 SSE4_2 AVX FP16 AVX2 AVX512_SKX
      SSE4_1 (13 files):         + SSSE3 SSE4_1
      SSE4_2 (1 files):          + SSSE3 SSE4_1 POPCNT SSE4_2
      FP16 (0 files):            + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 AVX
      AVX (4 files):             + SSSE3 SSE4_1 POPCNT SSE4_2 AVX
      AVX2 (26 files):           + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 FMA3 AVX AVX2
      AVX512_SKX (3 files):      + SSSE3 SSE4_1 POPCNT SSE4_2 FP16 FMA3 AVX AVX2 AVX_512F AVX512_COMMON AVX512_SKX

AVX is supposed to be a dispatched (optional) feature, but it is actually required??

janecek1980 commented 4 years ago

I have this problem as well.

OpenCV should check if AVX is available when loading the libraries, however there seems to be a bug in an initializer which runs an AVX instruction which than causes the crash: https://github.com/opencv/opencv/issues/15690

This is related to _OpenCV 4.1.1 and 4.1.2_. If I understand it correctly, it should have been resolved for 4.2 - but it does not seem that way.

mpolicki commented 4 years ago

opencv-4.2.0-vc14_vc15.exe does not include opencv_contrib, so you need to build OpenCV(with contrib) yourself in order to build OpenCvSharpExtern.

I tried doing this, but I was unable to build a debug version of OpenCvSharpExtern.dll equivalent to your release version. (I was able to build, with much trickery, a ~20MB debug version of OpenCvSharpExtern.dll which didn't exhibit the original problem, presumably because it didn't include the AVX-containing function.)

It seems this problem is another instance of opencv/opencv#15690, as @janecek1980 mentioned.

shimat commented 4 years ago

I made DEBUG version of OpenCV4.2.0 lib files. https://drive.google.com/open?id=1MnY0sR13y2lLrN1x0vGplbxedMhMcat5

(The DEBUG lib files are too large to upload to GitHub unless I use Git LFS.)

blaisexen commented 4 years ago

Hi, Beginning 4.2.0 (23 Jan., 2020) Unable to load DLL 'OpenCvSharpExtern'

tested under x86 and x64 before that, it's all Ok.

ArXen42 commented 4 years ago

Can confirm, encountered the same problem on user PC with Pentium G2030 (Windows 7). Also have seen it on windows 10 on other PC. In both cases older versions of software that were using OpenCV3 worked.

The fun part was that unless content of dll/x64 directory is copied to the root, there actually won't be any 0xC000001D exception, only more generic 0x8007007E or something like that (not very google-friendly error).

simonbuehler commented 4 years ago

i tried to build a debug opencv version with contrib but i get lots of unresoved symbols for img_hash, any idea what i did wrong?

grafik

simonbuehler commented 4 years ago

ok, the sharpextern project needs all generated opencv libs to be added in Project -> Properties -> Linker -> Input -> Additional Dependencies . The dll got build, testing now

blaisexen commented 4 years ago

@simonbuehler , well wait for that link :)

mpolicki commented 4 years ago

I made DEBUG version of OpenCV4.2.0 lib files.

I've built OpenCvSharpExtern.dll using these. However, with this DLL, I can not get VS to break on the actual offending instruction, despite having native code debugging enabled. It just shows the DLL not found exception, like it did previously when I had native code debugging disabled (and I've verified in the output window that it's repeatedly loading and immediately unloading the correct DLL). I have no idea why this is happening. Analyzing in DebugDiag didn't help either.

bbday commented 4 years ago

There is simil issue with emgu project when use opencv 4.2 library https://github.com/emgucv/emgucv/issues/297

Pavelyev commented 4 years ago

I'm trying to create web service with face detection on netcoreapp3.1 https://github.com/Pavelyev/CoreFaceDetector Project is being published with Self-Contained mode and win-x64 runtime. *.runtime packages are also referenced

<PackageReference Include="OpenCvSharp4" Version="4.2.0.20200208" />
<PackageReference Include="OpenCvSharp4.runtime.win" Version="4.2.0.20200208" />
<PackageReference Include="OpenCvSharp4.Windows" Version="4.2.0.20200208" />

On my machine it works fine (Microsoft Windows 10 Enterprise LTSC (10.0.17763 N/A Build 17763)) But on server (Microsoft Windows Server 2012 R2 Standard (6.3.9600 N/A Build 9600)) it throws following exception on new CascadeClassifier(path) call:

 ---> System.DllNotFoundException: Unable to load DLL 'OpenCvSharpExtern' or one of its dependencies: A dynamic link library (DLL) initialization routine failed. (0x8007045A)
   at OpenCvSharp.NativeMethods.redirectError(CvErrorCallback errCallback, IntPtr userdata, IntPtr& prevUserdata)
   at OpenCvSharp.NativeMethods.LoadLibraries(IEnumerable`1 additionalPaths)
   at OpenCvSharp.NativeMethods..cctor()

PublishReadyToRun option in publish profile doesn't affect the result Is there anything I can do?

ArXen42 commented 4 years ago

@Pavelyev as far as I understand, current version of OpenCVSharp won't work on processors without AVX2 instruction set. If you can't change your server to something with more modern CPU, the only solution (aside from actually managing to fix it in OpenCV(Sharp) sources) is to downgrade to something like 4.1 or 4.0 version.

If you will do this, please tell what version don't have this issue. I'm planning to downgrade OpneCV in my project too, but don't have suitable PC to reproduce the issue, so can't know for sure which version started this.

Upd. I can confirm that version 4.0 works on user PC where 4.2 don't. Too bad it doesn't have that neat Canon RAW support :(

M4nju commented 4 years ago

@ArXen42 I used the OpenCvSharp4.Windows with Version 4.0.1.20190326 and that worked for me. (Before we had and older version of the deprecated Nuget package OpenCvSharp3-AnyCpu which lead to an services crash. In the first step i updated this package which lead to the "Missing OpenCvSharpExtern" exception.) Hope this helps.

CityAndTheStars commented 4 years ago

Is there any official response from the authors maintaining OpenCvSharp? I am trying to make this work for OpenCvSharp4, UWP, x86 build.

shimat commented 4 years ago

I have released the new OpenCvSharp(4.3.0). Does the problem still occur in 4.3.0?

blaisexen commented 4 years ago

I have released the new OpenCvSharp(4.3.0). Does the problem still occur in 4.3.0?

thank you and Stay at home :dango:

janecek1980 commented 4 years ago

Thank you, works for me even on older CPUs.

itzukah commented 4 years ago

image

still i facing the problem sir. Hope to get help from you. Thanks

shimat commented 4 years ago

Please try reinstalling NuGet. I don't know why, but sometimes it fixes the error.

Update-Package -reinstall

If it doesn't solve your problem, try to check the dependencies of OpenCvSharpExtern.dll with a tool such as DependencyWalker.

Superllb93 commented 4 years ago

@shimat This problom occured when I deployed app to Azure Function, while my app run normally on local machine. Version is 4.3.0.20200421, .NET Core2.1

On the server, OpenCvSharpExtern.dll locates at runtimes\win-x64\native\ dir

Kant8 commented 4 years ago

Migrated project from NetFramework 4.7.2 to NetCore 3.1 and now dll/[x86|x64] folder is missing just after executing build in VisualStudio. Dlls are moved to runtimes folder as mention aboved. WindowsLibraryLoader's static constructor throws exception that it cannot find Extern.dll and swallows it immediately for some reason.

at OpenCvSharp.WindowsLibraryLoader.LoadLibrary(String dllName, IEnumerable`1 additionalPaths) 
   in C:\projects\opencvsharp\src\OpenCvSharp\PInvoke\WindowsLibraryLoader.cs:line 119

Manually creating dll\x64 folder and copying libraries resolves issue, but how to fix it to make everyting working automatically again?

Was on version 4.2, then updated to 4.3, nothing changed.

Kant8 commented 4 years ago

Actually problem with netcore and netstandard is because of this commit However I don't understand why this rules should be skipped.

If you don't specify exact runtime identifier in project runtimes folder is created all the time, but WindowsLibraryLoader doesn't search there at least by default.

And even if you set exact runtime identifier in project file, OpenCvSharpExtern.dll will be located in the same folder as application, but still won't load because LoadLibraryInternal method always adds dll to the path, and we never have dll because of that commit.

shimat commented 4 years ago

I believe that WindowsLibraryLoader is not necessary for .NET Core. The native DLLs are automatically path-resolved with "runtime/[RID]/native". https://github.com/shimat/opencvsharp/blob/master/nuget/OpenCvSharp4.runtime.win.nuspec#L28

.NET Framework cannot properly select x86 and x64 DLLs at runtime, and there is no path for native DLLs such as runtimes\win-x64\native in the .NET runtime specification, so I prepared WindowsLibraryLoader.

Many people have commented on this issue, but it works fine for me.

Kant8 commented 4 years ago

I checked with ProcessExplorer and yes, Extern.dll is loaded by itself , but after that exception is thrown and swallowed. Looks like TryPInvoke() loads it as inteded.

So maybe you should skip https://github.com/shimat/opencvsharp/blob/master/src/OpenCvSharp/PInvoke/NativeMethods/NativeMethods.cs#L92 for .netcore (maybe only when additionalPaths variable is empty, if that'll be safer).

shimat commented 4 years ago

Thanks 🙆‍♂️ https://github.com/shimat/opencvsharp/pull/947

DimitrisSevastakis commented 4 years ago

Hi, I am still getting this issue on OpenCVSharp4.Windows 4.3.0.20200524. When targeting either .net 4.6.1 or 4.7.2. Was this fix included in this version?

DimitrisSevastakis commented 4 years ago

I found out that when i use [DeploymentItem("Resources")] in my unittest it cannot find the dll. As soon as i remove it, everything works again.

shizal commented 4 years ago

In Microsoft Visual Studio 2019, be sure that you get the Runtime DLLs with using Nuget Packet Manager : Install-Package OpenCvSharp4.runtime.win -Version 4.3.0.20200524

Have a nice coding...

huanbd commented 4 years ago

Hi, I have same error like that. I've try to some version from 4.4 down to 4.2, but still error, when I've changed to version 4.1, It run perfect. I don't know why

BenSmithYoti commented 2 years ago

@mpolicki any chance of getting a copy of your fixed OpenCvSharpExtern.dll? Currently am locked into very specific versions and need to deploy asap onto machines with CPU without AVX2 support. If there was any way for you to share your fix it would be hugely appreciated. Thanks so much.

I tried doing this, but I was unable to build a debug version of OpenCvSharpExtern.dll equivalent to your release version. (I was able to build, with much trickery, a ~20MB debug version of OpenCvSharpExtern.dll which didn't exhibit the original problem, presumably because it didn't include the AVX-containing function.)

It seems this problem is another instance of opencv/opencv#15690, as @janecek1980 mentioned.

mpolicki commented 2 years ago

@BenSmithYoti I'm sorry, I no longer have any of those files.

BenSmithYoti commented 2 years ago

@mpolicki Oh well - was worth a shot. Thanks for the rapid response, really appreciated.

BenSmithYoti commented 2 years ago

@shimat first thanks so much for this excellent resource, absolutely awesome!

I am wondering if you might be able to point me in the right direction. It seems the .Net Framework version support drops off on the more recent nuget packages. I wonder if this is unavoidable?

I am stuck needing to target net45 and have come across this issue (CPUs without AVX2 support), which seems (I believe?) to boil down to an issue in specific OpenCv releases (?) https://github.com/opencv/opencv/pull/15704 https://github.com/opencv/opencv/issues/15690 etc ?

I would just update the OpenCvSharp nuget references (OpenCvSharp4 and OpenCvSharp4.runtime.win currently on 4.2.0.20200108) which has support for .Net 4.0), but it seems that is the last version that I can use.

Looks like from https://www.nuget.org/packages/OpenCvSharp4/4.2.0.20200208 upwards its 4.6.1 +

Almost at QA/production and then just today found this AVX2 issue when testing on a Celeron CPU.

Wonder if you have any suggestions at all for any easy ways forward?

Thanks so much for sharing all your excellent hard work!

ticTechtoee commented 2 years ago

I was having this problem in production (After Creating the Setup File and Installing it). I've solved it by doing the following steps

  1. Installed the OpenCVSharp Through NuGet Packages
  2. Setting the Platform Target to X64 in Project Properties
  3. Creating the Setup File with the same Platform
  4. Manually Copying the "packages\OpenCvSharp4.runtime.win.4.5.3.20210817\runtimes\win-x64\native\OpenCvSharpExtern.dll" file into the installation directory.
TheCheatsrichter commented 1 year ago

Issue seems still present on:

Exe compiles fine, but as soon as a OpenCvSharp method is called:

System.TypeInitializationException: "The type initializer for 'OpenCvSharp.Internal.NativeMethods' threw an exception."
DllNotFoundException: Unable to load DLL 'OpenCvSharpExtern': The specified module could not be found. (Exception from HRESULT: 0x8007007E)

What I have tested so far:

What I have observed;

I hope this info helps a bit. Are there any news on how to solve this issue?

leixun317 commented 6 days ago

Inspecting the output revealed that shortly after the app successfully opens OpenCvSharpClassLibraryTest\ConsoleApp1\bin\Release\dll\x86\OpenCvSharpExtern.dll

x86??? Your environment is x64, but the x86 DLL is loaded...

OpenCvSharp controls the target DLL file path for C# DllImport by loading the dll/[x64 or x86]/OpenCvSharpExtern.dll in advance with the Win32API LoadLibrary function. If the platform setting is AnyCPU, the program must determine whether the native DLL to be loaded at runtime should be x64 or x86.

As a workaround, manually copying dll/x64/OpenCvSharpExtern.dll to the same folder as the exe file may make the program work. copy dll/x64/OpenCvSharpExtern.dll ..\..\

OpenCvSharp4 is very perfect, Can you make an android version, thanks

leixun317 commented 6 days ago

OpenCvSharp4 is very perfect, Can you make an android version, thanks