I want to create an OpenCV wrapper to use it in C#. I am using this link as a reference http://drthitirat.wordpress.com/2013/06/06/use-opencv-c-codes-in-a-vc-project-solution-of-creating-a-managed-clr-wrapper/ So far I have created a C++ console application that contains my image processing code. Also I created a C++/CLI class library in which I wrapped the OpenCV code, but when i try to build it I get a lot of unresolved externals errors about OpenCV functions used in the C++ code and I don't know how to fix it... Any idea how to fix the problem? Is there a simpler, easier way of using C++ OpenCV code in C#? I don't want to use Emgu or any other wrapper, my image processing code has to be in C++.
-
3Why don't you use an existing OpenCV .NET wrapper? http://www.emgu.com/wiki/index.php/Main_Page – Mihai Hantea Mar 03 '14 at 13:12
-
No, unfortunately my image processing code must be written in C++. – DBWhite Mar 03 '14 at 13:15
-
Maybe this can help you continue http://stackoverflow.com/questions/9521916/wrapping-c-for-use-in-c-sharp and http://stackoverflow.com/questions/2637571/creating-simple-c-net-wrapper-step-by-step – Mihai Hantea Mar 03 '14 at 13:18
-
Unresolved externals are missing lib files in linker command. Just fill the additional library directories and in the input fill in your lib files. Other thing is when you need to use images in C#, you have to convert between OpenCV image struct to Bitmap. – stepandohnal Mar 03 '14 at 14:13
-
Yeah, I added the property sheets both for Debug and Release and checked everything but the errors are still there. I don't know what to do... Any advice on the conversion between Bitmap and Mat? – DBWhite Mar 03 '14 at 14:41
1 Answers
How I solved the problem with opencv using visual studio 2012:
- I created a c++ image processing library with opencv and compiled it to a static library (.lib) as mentioned here. Basically, create an console application project and change in Project configuration -> General -> Configuration type to a "static library (.lib)". That will compile your project to a .lib file which later you should use in c++/cli.
- Then i made a C++/CLI wrapper - for each class in c++ I was about to publish to c# I made a wrapper like in this link. I used existed headers from c++ just by adding to project like Add to project -> Existing Items and choose headers from project 1. This also have an advantage that if you change something in .lib file, you have the same .h files so when you recompile .lib, you don't have to change headers in c++/cli. I included .lib from 1. going to Project properties -> Linker -> Input -> Additional dependencies and put the path to the .lib file. This project was compiled to .dll file. (Project configuration -> General -> Configuration type -> "dynamic library (.dll)").
- In c# project I've just add to references the .dll and used classes from c++/cli , which are managed classes. And that is how magic works.
Remark A: I can assure that this solution worked. I used features like pattern detection and camshift with opencv 2.4.2.
Remark B: Another topic is how exactly marshalling should be made. In case of simple data types, there is no doubt in using c++/cli data types like UInt32 etc. But the question is if you want to pass more sophisticated objects like cv::Mat which do not have types direct equivalent in c++/cli. In that case, I made simplified version of such classes on c++/cli side.
Remark C: Don't mess architecture in different projects. If you are using e.g. x86, be consequent in all projects.
Remark D: Practically, the problem using c++ code in c# has two solutions: the one I described and the direct calling to c++ unmanaged code from c# managed code using dynamic on-the-fly marshalling. There are two major disadvantages: on-the-fly marshalling takes time and you do not really know how exactly do this between complex data types (namely, everything what is different than int or string). So c++/cli it is really a good option because you are able to mix managed and unmanaged code.
Remark E: This solution is general, it does not count only in opencv. I successfully used this making c++/cli wrappers to rotation stages (motor devices) which only have c++ drivers and used that drivers in c# code.
Regarding Remark C: Use a dependency walker like Depends (http://www.dependencywalker.com/) to see which dependencies are not consistent.
-
I'm confused about creating the static library. Is this it http://msdn.microsoft.com/en-us/library/ms235627.aspx ? How to include it in the wrapper? Thanks for your help. – DBWhite Mar 03 '14 at 22:52
-
-
-
@marol i'm trying to use you solution however i'm getting Error 1 error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MT_StaticRelease' doesn't match value 'MD_DynamicRelease' in CLRWrapper.obj, this means that the openCV staticlib is not complied with flags which suites the same linking like the C++/CLI project. how did you overcome this problem? – Gilad Apr 26 '15 at 15:14
-
@Gilad Basically I did not face such problem. Maybe this http://stackoverflow.com/questions/14714877/crypto-mismatch-detected-for-runtimelibrary might help. Maybe you have debug/release mismatch? – marol Apr 27 '15 at 19:09
-
Following above steps, was able to produce the desired result. Now i need to add cross platform compatibility also, adding support for linux platform. What would be the best approach to do so? – Amit Dec 06 '18 at 07:50