Using OpenCV C++ function in C# Xamarin Android Project - c#

I'm currently working on making an Android app with Xamarin to recognise fiducial markers using OpenCV's ArUco module. I've crossed the first hurdle of finding a C# binding of OpenCV located here. I realised that the ArUco module which I need is not included in the standard OpenCV build as it belongs to the contributor modules in a separate repository. After much research online (I don't have much experience with C++ or C#), I managed to build OpenCV for Android with the ArUco module included, including the .so shared library files into my Visual Studio solution under the appropriate folders. I then attempted to call a C++ function getPredefinedDictionary to see if I can figure out the P/Invoke stuff. This is where the app crashes with no clear explanation (to me). I am fairly confident it is to do with me using dllimport incorrectly to get the C++ function. The full text is linked below, but the main part seemed to be:
Got a SIGSEGV while executing native code. This usually indicates a fatal error in the mono runtime or one of the native libraries used by your application.
The getPredefinedDictionary from dictionary.cpp looks like this:
Ptr<Dictionary> getPredefinedDictionary(int dict) {
return getPredefinedDictionary(PREDEFINED_DICTIONARY_NAME(dict));
}
I attempt to call it from my C# code like this:
public ArUcoMarkerDetector()
{
IntPtr dictionary = getPredefinedDictionary(value);
}
[DllImport("libopencv_aruco.so", EntryPoint = "_ZN2cv5aruco23getPredefinedDictionaryEi")]
private extern static IntPtr getPredefinedDictionary(int dictionary);
From looking at the OpenCV documentation, I understand that Ptr<Dictionary> is a class but not much more than that. My main question is how can I correctly use this in my C# project? Or at the least, debug this error message properly?
Full error message: https://pastebin.com/05jQbmV2

Related

error LNK1181 in cmake project with static/shared libs [duplicate]

I've got a library definition in CMake that builds a shared library out
of a small set of files, and I've got it compiling just fine on both linux and windows.
However, I've also got another library that links against the shared library and it works fine on linux, however, on windows I get a message along the lines or "error can't find Release/nnet.lib" during link-time. Is there something special I have to do to get this to
link on windows?
Edit, example:
Main shared library (filenames changed to protect the innocent):
ADD_LIBRARY(nnet SHARED
src/nnet/file_1.cc src/nnet/file_3.cc
src/nnet/file_2.cc src/nnet/file_4.cc)
And then I'm building a python module that links in the library:
# Build python module
ADD_LIBRARY (other_lib SHARED ${CMAKE_SOURCE_DIR}/src/boost/boost_main.cc)
TARGET_LINK_LIBRARIES (other_lib nnet ${PYTHON_LIBRARIES})
The rest is just boilerplate (eg: changing module extension to .pyd on windows, finding python libraries/headers, etc)
And then when building in VS 2008 I get:
fatal error LNK1181: cannot open input
file 'Release\nnet.lib'
when building other_lib. Note no errors are thrown while building nnet.
Ah, my problem was I forgot to include a __declspec(dllexport) in suitable places when building the library (can you tell I don't do windows programming a lot?).

gcc DLL from C#: “DLL initialization routine failed” on Windows 10

I am developing C# DLL that needs a code I have as a C++ DLL, build by gcc.
For this, I have written a C wrapper and compiled it using gcc (TDM-GCC MinGW-w64) as a DLL. In other words, I have:
C++.dll built by gcc; plus C++_test.exe that uses the DLL, so I know it works.
C.dll built by gcc, calling C++.dll; plus C_test.exe that uses the DLL...
C#.dll built by Visual Studio, calling C.dll; plus C#_test.exe
The whole chain is built as 64-bit code.
My problem is that while this setup worked fine on my old Windows 7 box, on my new machine with Windows 10 (and also newer versions of software and libraries), C#_test.exe fails at the point it calls a function from C.dll, with the following message: Unable to load DLL 'C.dll': A dynamic link library (DLL) initialization routine failed. (Exception from HRESULT: 0x8007045A)
In the C# code, the function is defined as:
[DllImport("C.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int pg_generate(..);
I have all the other DLLs in the same folder (otherwise I would get another error message about missing DLL).
Any idea how to find out what the problem is and how to fix it?
I know that it would probably help to build the whole chain in VS, but I do not have the required project files and would also build several libraries that C++.dll depends on, so I would rather avoid that - especially since it worked before...
Update: When I debug C#_test.exe in VS, it throws from pg_generate(): Exception thrown at 0x000000006E0436B0 (C++.dll) in C#_test.exe: 0xC0000005: Access violation reading location 0xFFFFFFFFB64927F5.
Update 2: I get the same error (DLL initialization routine failed) also when I used C#_test.exe (and all dependencies) built and tested on my old box. This suggests that the problem is in Windows 10 vs. Windows 7.
(It also means that once the client upgrades to Windows 10, the code we delivered will stop to work...)

Bad Image Format VS DLL Not Found

I've got a problem loading a C DLL through a C# wrapper class. I have done some research, and I have not yet gotten a satisfactory solution from doing any of the below
Changing my solution's target platform.
Changing my project's target platform.
Changing the platform in the configuration's manager.
The C DLL that I'm trying to use is 64 bit, so I initially tried setting everything to 64 bit and accessing the DLL through my wrapper class. When I did this, I got a DLLNotFoundException. Perplexed because my DLL was definitely on the build path, I tried setting everything to 32 bit, at which point, it looks like my DLL was found, but I was getting a Bad Image Format Exception on the same line.
What could this mean, and where should I go from here?
The library I'm trying to use is the DualAlign I2KRetina library; trying to adapt it to C#. The experimental code that I'm running is very simple (below). I am not presenting the wrapper class (which I got from DualAlign) because it's pretty large, and I have no reason to doubt that it is working (yet) =).
class TestImage2
{
public static void Main(String[] args)
{
TestMontageMethod();
Console.ReadLine();
}
public unsafe static void TestMontageMethod()
{
IntPtr license_file_path = DA_CSharpCls.da_i2k_expected_license_path();
}
}
The line that's giving me trouble is the license_file_path assignment. A big thank you to everyone who contributes!
You've fixed the BadImageFormat exception by compiling in 64-bit; now it seems like either you can't find the DLL or it is missing a dependency.
First thing to check is that the DLL exists in the path or in the output directory if your build; keep in mind that it may be different for each build (x86, AnyCPU and x64) so the library may need to be copied to that directory either by you manually or through the reference properties in VS.
If you've established that the DLL does exist, then it is likely a dependency issue. Download the 64bit version of dependency walker and it will show you what is missing.
Have you check the framework version difference between two DLL. This can cause issue sometime.

How can I call my C# code from a C++ dll? Access violation

Background:
Big C++ MFC app that's not going to get rewritten any time soon. A few years ago I needed to add features and decided that it would be easier built with C# and .NET, so I needed a way to call into .NET functions with the C++ app. At the time we were using VC6.0 for the MFC app, and we built the .NET functionality using VS.NET 2003 and .NET 1.1. In VS.NET 2003 we built a regular win32 dll (no MFC) with exported functions that the MFC app could consume. The dll functions referenced our .NET assemblies and it all worked great. Now, our MFC app is still an MFC app, but it is compiled with VS9, and it still works fine with the old 2003 compiled dll. However, we are now faced with creating a new DLL (new features) and are building it with VS9 and .NET 3.5.
The problem:
I've created the new DLL with the /clr option. I've got an options form in our .NET assembly that I'm trying to invoke from the exported dll function.
I get an unhandled exception message like this:
Unhandled exception at 0x04359108 in IP2000.exe: 0xC0000005: Access violation reading location 0x00000000
The code that it doesn't like looks something like this:
FooTools::frmConfiguration ^ frmConfig = gcnew FooTools::frmConfiguration();
frmConfig -> ShowDialog();
The syntax has changed. We used to use * and new instead of ^ and gcnew, but the old syntax won't compile (not sure if that's an issue anyhow).
I've tested that the exported function is getting called by placing a straight win32 ::MessageBoxand it gets called. I also tried calling some different managed code from the exported function, ie. System::Windows::Forms::MessageBox->Show ... , and it also worked fine. It just doesn't want to run this form.
It seems to me that something must have changed between VS 2003 and VS9 that is causing me some grief, but I can't seem to see what it is.
This form works fine if called from a test Windows.Forms app.

How do I solve the .NET CF exception “Can't find PInvoke DLL”?

This is to all the C# gurus. I have been banging my head on this for some time already, tried all kinds of advice on the net with no avail. The action is happening in Windows Mobile 5.0.
I have a DLL named MyDll.dll. In the MyDll.h I have:
extern "C" __declspec(dllexport) int MyDllFunction(int one, int two);
The definition of MyDllFunction in MyDll.cpp is:
int MyDllFunction(int one, int two)
{
return one + two;
}
The C# class contains the following declaration:
[DllImport("MyDll.dll")]
extern public static int MyDllFunction(int one, int two);
In the same class I am calling MyDllFunction the following way:
int res = MyDllFunction(10, 10);
And this is where the bloody thing keeps giving me "Can't find PInvoke DLL 'MyDll.dll'". I have verified that I can actually do the PInvoke on system calls, such as "GetAsyncKeyState(1)", declared as:
[DllImport("coredll.dll")]
protected static extern short GetAsyncKeyState(int vKey);
The MyDll.dll is in the same folder as the executable, and I have also tried putting it into the /Windows folder with no changes nor success. Any advice or solutions are greatly appreciated.
Maybe this seems like an obvious thing to check, but are you compiling the native DLL for the correct CPU architecture? IIRC, Windows Mobile runs on multiple CPU architectures.
I have the same problem, but this time there is no obvious difference in the platforms involved. Why is it something that is supposed to be 'normal' is so badly documented, so difficult and worst of all so 'flaky'.
Are there ANY tools that allow me to go onto my PPC emulator, and stop by step check (a) that the dll is where CLR expects it (I have put it both in the same directory, and the windows directory on the emulator - I can see it is there usign the emulators file explorer), (b) that CLR can load it (has enough memory etc), (c) that CLR can then find what functions are present (useful if I can get beyond the stupid 'can't find the dll' error)
I'd love to force Gates or indeed any of the 'windows mobile' team to use the crap they create.
The exception you listed and the pinvoke signature you put in the question have different names: MyDll.dll and ThreadBenchLib.dll respectively. Was that a typo or the problem?
If it's not the problem try opening the DLL in depends. It's possible the DLL load is failing because of an unmet dependency.
I am having the same problem. I used the Depends.exe to look for WinCE dll dependencies, and It depends of debug dll. (MSVCR90D.dll)
To solve the problem I compiled a release version, and confirm the dependencies, after that it works fine.
I hope to help

Resources