OpenCV 4.5.2 Android in Visual Studio 2019

I try to compile a .so library using Visual Studio 2019 along with OpenCV Android in order to use this library in Unity.
There are some answers on how to configure Visual Studio to use OpenCV Android (here or here) but none of these work for me. Below you can see my configurations.

Visual Studio 2019 (running on Windwos 10)

android-ndk-r21e // also tried with android-ndk-r15c android-ndk-r16b and android-ndk-r17c

OpenCV Android 4.5.2 // also tried with OpenCV Android 4.0.0, 4.0.1 and 4.1.0

My settings in Visual Studio 2019 look as follows:

Configuration Properties

- General

  • Platform Toolset Clang 5.0 (also tried Clang 3.8 or GCC 4.9)

  • Configuration Type Dynamic Library (.so)

  • Target API Level Nougat 7.0 (android-24) (also tried different versions)

  • Use STL LLVM libc++ static library (c++_static) (also tried “GNU STL static library (gnustl_static)”)

C/C++

- General

  • Additional Include Directories “Path to OpenCV_4_5_2_Android\sdk\native\jni\include”

  • Code Generation Enable C++ Exceptions “Yes(-fexceptions)”

  • Language C++17(-std=c++1z)

  • Precompilied Headers Not using Precompiled Headers

Linker

- General

  • Additional Library Directories Path to OpenCV_4_5_2_Android\sdk\native\libs\armeabi-v7a

- Input

  • Additional Dependencies Path to OpenCV_4_5_2_Android\sdk\native\libs\armeabi-v7a\libopencv_java4.so

My Source.cpp I try to compile is just a single function for testing purposes

#include <opencv2/core.hpp>
extern "C" float test(float a, float b)
{float c = a * b;	return c;}

Wich gives me the following errors:

E0035 #error directive: This constructor has not been ported to this platform
E0020 identifier "__fp16" is undefined
use of undeclared identifier 'ANDROID_LOG_INFO'

The ANDROID_LOG_INFO error can be fixed when I add #include "android/log.h" at the top of the file that throws this error. But the other two errors still remain.

I too have this same problem. I will add that I tried it with OpenCV 3.4.14 (in addition to 4.5.2).

I also followed the same directions from the sites linked above (and was unable to find any other pages that talked about creating a .so through Visual Studios).

I found that the error goes away when no OpenCV header file is included, which of course defeats the purpose. I have very little C++ experience but I believe OpenCV must somewhere have its own “typedef __fp16 ???” line, because I can generate the error by adding to my code (after removing any OpenCV includes) my own typedef line. By adding

typedef __fp16 float16_t;

This is in fact what arm_neon.h is defining it as, and arm_neon.h is included as an External Dependency (I don’t know where the statement is that ultimately points to it so that it is included).

So I believe an OpenCV header file defines __fp16 as something and arm_neon.h also defines it as something (possibly the same thing, either way this error occurs).

Same problem, exactly. To add to the data here, I followed Amin Ahmadi’s tutorial from scratch, including cross compiling from the source, using 4.0.1. and NDK 16rb to keep with his example and my client’s needs, and it didn’t help.

I suspect it is an issue with the LLVM toolchain defaults that Visual Studio now populates into the Shared Library solution template, but I’m not sure what we’d replace those with.

Also, force-fixing the float16 issues in arm_neon.h uncovers a whole lot of other errors…

UPDATE: This is going to sound really dumb, but try simply building it (not running) with your main .cpp file highlighted. I find that it succeeds despite the slew of complaints from arm_neon.h. which could just be some kind of Intellisense issue. Whether or not what the compiler spit out for me works is TBD.

don’t worry about compiler warnings. plenty of libraries were/are written with hardly any compiler warnings enabled… and then the craft evolves and ever more warnings are enabled by default, which causes warnings all over the place. you’d have to look at specific instances and judge them.

do be careful if there were actual errors. some build systems show you those once, but still generate an object file for that module (or some other thing that causes the source to be ignored next time), which means it won’t be compiled again (until the source changes)… so you won’t see those errors again either, until you do a clean build of everything.

Well, In Unity on my OpenPlus 6T I get a “Failed to find cascade definition” instead of the old “Missing DLL” error, so I guess that’s progress? I’m using the object finding code, and I must have just put the xml file in the wrong spot.

1 Like

I finally tried to compile my .so libraries in Android Studio. There I also get some compiler errors but as crackwitz said my libraries are build anyways somehow.

1 Like

Did you get the camera stream on android to work with the code? My WebCamTexture is definitely working and showing my face in the camera, but OpenCV doesn’t find the stream.

My camera stream comes from a C# script I created in Unity. I send my frames as Color32.

Cool. Can I ask what android ndk you used with it? The one I solved the issues for was 4.0.1 – I assumed it would also work for 4.5.2 but it hasn’t yet for me and I need to update, but 21e seems broken.

I finally downgraded OpenCV Android to 3.4.14 and use ndk 16b. So I still don’t know if version 4.5.2 works.

You’re right, I’m not sure that it does. I was able to build 4.5.2 from the source using ndk 21e’s toolchain instead of the one that came with 4.5.2 (on the advice of the github repository’s developers), but the Visual Studio compiler still gives a million errors about not recognizing all the std::math functions. Hrm.

Any advice here, anyone? Not asking to troubleshoot Visual Studio, but I am wondering why errors like these would come up if everything else is correct:
error : no member named ‘isless’ in the global namespace
1>using ::isless;
error : no member named ‘islessequal’ in the global namespace
1>using ::islessequal;
(etc.)

Figured out how to actually build from 4.5.2 successfully (my previous solution above only worked for 4.0.1).

-build from the source with CMake using Android NDK 21e, but instead of the toolchain in OpenCV 4.5.2, use the toolchain in the NDK build folder (this comes from the horse’s mouth, and it works).
-once you’re in Visual Studio, use these changes:
in Properties/ Configuration / General, use LLVM libc++ static library instead of the GNU static library. This is because GNUc++ was removed from Android NDKs after 17. THAT is why all those nutty errors pop up with standard libaries missing when you try to build with it.
In Linker / Input, put the library file name(s) in “Library Dependencies” instead of “Additional Dependencies”, or the linker will never find them.
-do everything else the same as most tutorials (c++ 11, etc.)

1 Like

So I built the library and ignored the errors (that is any that didn’t prevent building). But I still can’t call the library from Unity.

I tried a different route and made libraries strictly using text editors and CMake yesterday and the day before. I created both windows and Android libraries that I successfully called from Unity in their respective builds (for both 32-bit and 62-bit on Android), but I am having trouble getting OpenCV included in those builds (but I’ll post separately for that somewhere, I have pretty much no experience with CMake). However, this is proof that I am able to call .so libraries from Unity.

Because of my troubles with CMake I decided to try to just get a bare bones .so library built in Visual Studios from a clean project. Nothing in the code but a function that returns a hardcoded int. However, when using this library Unity still comes back with an error in Logcat stating:

“DLLNotFoundExepction: Unable to load DLL ‘name’: The specified module could not be found.”

In the same run I have my simple CMake made .so library that has the same simple function, and it works.

In Visual Studios I again selected “Dynamic Shared Library (Android)” and left all the project settings alone except I set:
LLVM libc++ shared library (c++_shared)
C++11 (-std=c++11)

Only other settings that were bolded, though they were set this way from the start were:
Clang 5.0
Dynamic Library (.so)

Anybody know why such a simple setup won’t work?