shimat / opencvsharp

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

Can't link `OpenCvSharpExtern` on Linux #376

Closed Anamon closed 7 years ago

Anamon commented 7 years ago

Summary of your issue

I can't figure out how to get my program to link the OpenCvSharpExtern library at runtime on Linux.

Environment

A 64-bit Linux Mint (LMDE 2 Betsy) VM with .NET Core v1.1.2, OpenCV 3.2.0 and OpenCvSharp3-AnyCPU at v3.2.0.20170419.

Linux version 3.16.0-4-amd64 (debian-kernel@lists.debian.org) (gcc version 4.8.4 (Debian 4.8.4-1) ) #1 SMP Debian 3.16.43-2+deb8u2 (2017-06-26)

What did you do when you faced the problem?

I tried to compile and run my .NET Core project using OpenCVSharp, which runs fine on Windows, on a Linux machine. I performed the following steps (after setting up the .NET Core toolchain):

Example code:

In project file:

<PackageReference Include="OpenCvSharp3-AnyCPU" Version="3.2.0.20170419"/>

In code:

using OpenCvSharp;

# Code in xUnit testcase:
Mat testImage = Cv2.ImRead("Input.jpg");

Run:

dotnet restore
dotnet build
dotnet test

Output:

It's the well-known dynamic linking failure that has been giving many other people trouble before:

[xUnit.net 00:00:01.5142311]     Namespace.Testcase [FAIL]
[xUnit.net 00:00:01.5277401]       System.TypeInitializationException : The type initializer for 'OpenCvSharp.NativeMethods' threw an exception.
[xUnit.net 00:00:01.5295641]       ---- OpenCvSharp.OpenCvSharpException : Unable to load DLL 'OpenCvSharpExtern': The specified module could not be found.
[xUnit.net 00:00:01.5308765]        (Exception from HRESULT: 0x8007007E)
[xUnit.net 00:00:01.5322714]       *** An exception has occurred because of P/Invoke. ***
[xUnit.net 00:00:01.5336770]       Please check the following:
[xUnit.net 00:00:01.5349880]       (1) OpenCV's DLL files exist in the same directory as the executable file.
[xUnit.net 00:00:01.5364421]       (2) Visual C++ Redistributable Package has been installed.
[xUnit.net 00:00:01.5378030]       (3) The target platform(x86/x64) of OpenCV's DLL files and OpenCvSharp is the same as your project's.
[xUnit.net 00:00:01.5394495]       
[xUnit.net 00:00:01.5410275]       System.DllNotFoundException: Unable to load DLL 'OpenCvSharpExtern': The specified module could not be found.
[xUnit.net 00:00:01.5431416]        (Exception from HRESULT: 0x8007007E)
[xUnit.net 00:00:01.5446565]          at OpenCvSharp.NativeMethods.core_Mat_sizeof()
[xUnit.net 00:00:01.5459460]          at OpenCvSharp.NativeMethods.TryPInvoke()
[xUnit.net 00:00:01.5470083]       -------- System.DllNotFoundException : Unable to load DLL 'OpenCvSharpExtern': The specified module could not be found.
[xUnit.net 00:00:01.5486279]        (Exception from HRESULT: 0x8007007E)
[xUnit.net 00:00:01.5502861]       Stack Trace:
[xUnit.net 00:00:01.5574166]            at OpenCvSharp.NativeMethods.imgcodecs_imread(String filename, Int32 flags)
[xUnit.net 00:00:01.5604129]            at OpenCvSharp.Mat..ctor(String fileName, ImreadModes flags)
[xUnit.net 00:00:01.5611202]            at OpenCvSharp.Cv2.ImRead(String fileName, ImreadModes flags)
[xUnit.net 00:00:01.5615574]         /home/username/Project/Filename.cs(33,0): at Namespace.Testcase()
[xUnit.net 00:00:01.5620643]         ----- Inner Stack Trace -----
[xUnit.net 00:00:01.5624050]            at OpenCvSharp.NativeMethods.TryPInvoke()
[xUnit.net 00:00:01.5627827]            at OpenCvSharp.NativeMethods..cctor()
[xUnit.net 00:00:01.5631150]         ----- Inner Stack Trace -----
[xUnit.net 00:00:01.5634355]            at OpenCvSharp.NativeMethods.core_Mat_sizeof()
[xUnit.net 00:00:01.5638368]            at OpenCvSharp.NativeMethods.TryPInvoke()
[xUnit.net 00:00:01.5685690]       Output:
[xUnit.net 00:00:01.5740603]         pwd: /home/username/Project/bin/Debug/netcoreapp1.1
[xUnit.net 00:00:01.6465541]   Finished:    Project

What did you intend to be?

Using the exact same codebase, the code should compile and run under Linux just the same as it does under Windows. The .DLL files packed with the NuGet release of OpenCvSharp3 seem to be Windows-only, but replacing them with a version compiled on the target Linux system from the OpenCvSharp codebase should result in a version that is possible to link and use.

Am I doing something wrong here, or missing a step?

Anamon commented 7 years ago

This is more than mildly embarrassing, but right after writing up this issue, I figured out my mistake. You're not supposed to copy the library to the executable directory (as many other answers suggest), but in the dll/<ARCH> subdirectory. Once the library could be found at dll/x64/libOpenCvSharpExtern.so, the program ran fine.

Sorry for the noise!

Josvds commented 6 years ago

Can you tell me where you did copy this to? I can`t figure out what folder it should be in? Root\ Root\bin\Debug\netcore2.0\dll\x64 Root\bin\Release\netcore2.0\dll\x64 Root\bin\Release\Publish\dll\x64

running with "dotnet run" and "dotnet project.dll" both are not working

Anamon commented 6 years ago

Depending on whether you're running your application in the debug or the release configuration, it should be either the second or third path in your list. dotnet run should be the command you use – is it giving you the same output as I pasted in the ticket description? Also, make sure the file is named exactly as in my reply, including the .so extension.

vinayakcybage commented 4 years ago

I've implemented .net core 2.2 web api, in which OpenCvSharp4 4.0.0.20190108 is used and it is working fine on windows container, but when deployed on Linux container it is throwing error "The type initializer for 'OpenCvSharp.NativeMethods' threw an exception.OpenCvSharp.OpenCvSharpException: Unable to load shared library 'OpenCvSharpExtern' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: libOpenCvSharpExtern: cannot open shared object file: No such file or directory ---> System.DllNotFoundException: Unable to load shared library 'OpenCvSharpExtern' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: libOpenCvSharpExtern: cannot open shared object file: No such file or directory\n at OpenCvSharp.NativeMethods.core_Mat_sizeof()\n at OpenCvSharp.NativeMethods.TryPInvoke()\n --- End of inner exception stack trace ---\n at OpenCvSharp.NativeMethods.TryPInvoke()\n at OpenCvSharp.NativeMethods..cctor()"

I tried:

Can someone guide me step by step to resolve this issue?

ArXen42 commented 4 years ago

@vinayakcybage what worked for me on ArchLinux:

  1. Built libOpenCvSharpExtern.so on my pc (there is section on that in README.md, surprisingly it takes only 5 minutes).
  2. Renamed it to just libOpenCvSharpExtern (no extension) and copied to /usr/lib/.
  3. Attempted to run dotnet program. It will likely fail with similar message, but instead of In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: libOpenCvSharpExtern: cannot open shared object file: No such file or directory ---> there will be some other library name, which you should install using your package manager. Alternatively, you can use ldd to get missing dependencies.

Using binary provided by OpenCvSharp package didn't work for me because it was compiled against specific versions of system libraries that are older than mine.

Currently trying to figure out how to make it work under docker.

sb-aanandh commented 2 years ago

I am still facing this issue. I have compiled "OpenCV 4.5" on Ubuntu 21.10 and "OpenCVSharp 4.5.5." successfully. Whenever I run the dotnet run / dotnet., it opens with the same error , unable to load the libOpenCVSharpExtern . What is the best way to resolve this.

LucasBeastBeast commented 3 days ago

@vinayakcybage you are a lifesaver. Thanks