emgucv / emgucv

Emgu CV is a cross platform .Net wrapper to the OpenCV image processing library.
https://www.emgu.com/
Other
2.09k stars 576 forks source link

Improve dependency management of cvextern.dll? #720

Open Gibtnix opened 2 years ago

Gibtnix commented 2 years ago

Hello,

I came across using EmguCV some time ago because using OpenCV as shared libraries is a very convenient option to use regular OpenCV functions with C++ (directly linking to the respective OpenCV DLLs) while also doing the same in C#. However, this way I noticed that the dependencies can be a bit over-complex. Using shared libraries, cvextern.dll links against all respective OpenCV DLLs and also does a good job in trying to resolve all its dependencies (I also made a PR regarding loading DLLs from the Path environment variable before).

However, recently I noticed the following issue. Assume I need some small image processing functionality in C# and include EmguCV's C# assembly. At runtime, the program depends on cvextern.dll and thus also on all OpenCV libraries even though only a fraction of them is actually used at runtime. Therefore I thought it might be a good idea to add delay load functionality while compiling cvextern.dll for all opencv_module.dlls, except maybe opencv_core.dll?

This would allow to only depend on the actually required libraries, similar to C++. It is relatively easy to enable this in the project properties of cvextern.dll by adding the respective linker flags. Thus I thought that this might also be a useful additional default functionality in the CMake setup and hence wanted to mention it here.

emgucv commented 2 years ago

The cvextern.dll file currently contains C interfaces to all opencv modules, the C interfaces need to be linked to opencv modules in compile time, and will have dependencies on all modules.

One option is to break up cvextern.dll to serveral dlls (e.g. cvextern_core.dll, cvextern_imgproc.dll, cvexterndnn.dll) where each cvextern{module}.dll contains only the C interface for that module. Then load the cvextern_{module}.dll on demand. The PInvoke entry point will need to be modified too. It could be a huge task.

You are welcome to give it a try and contribute with a pull request. Thank you.

Gibtnix commented 2 years ago

Thanks for your comment. Actually, I find the current solution using a single cvextern.dll only not so bad. If you use static OpenCV libraries, everything is compiled into a single DLL. But what do you think about using delay loading to OpenCV DLLs?

I think this is the best solution because it maintains a single interface DLL (cvextern.dll) such that in case of static linking to OpenCV nothing changes. In case of dynamic linking to OpenCV, only the required DLLs are loaded at runtime as required. I presume it requires a few extensions of the CMakeLists.txt to define the respective linker flags. Optionally, also some minor extensions of the initialization logic in the C# code are possible, but not required.

I'm open to analyze this in a bit more detail and maybe create a PR that realizes the delay loading. But does that agree with your plans? I just don't want to spend the time working on the CMake configuration if the PR won't be merged thereafter.