4
votes

I have Xamarin forms cross platform project - Android, iOS and UWP. I have a C++ DLL project from which I have created a DLL. My intention is to integrate/call these C++ code within Xamarin forms cross. I know how to call C++ from C# Console application with DLLImport assembly directive, but on Xamarin I get DllNotFoundException.

So where the DLL file has to be copied or referenced for this to work?

  • I have copied .dll and other files in Debug folder(where the current project is trying to reference DLL. (I referred this video and it works for C# console )
  • Even tried Add Reference to DLL file - gives error cannot add file
  • Adding C++ DLL project to same solution and referencing it is giving System.DllNotFoundException.
  • Created cross platform shared C++ (I think this is comes in NDK)library project but still get the same issue - DllNotFoundException.

Code :

  1. C++

    #include "stdafx.h"
    
    extern "C"{
    
        __declspec(dllexport) int add(int a, int b)
        {
            return a + b;
        }
        __declspec(dllexport) int subtract(int a, int b)
        {
            return a - b;
        }
    }
    
  2. App.xaml.cs or any other .Net standard shared project

    public partial class App : Application
    {
    [DllImport("Dll1.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int subtract(int a, int b);
    
    
    [DllImport("Dll1.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int add(int a, int b);
    
    [DllImport("XamCppDll.Shared.so")]
    public static extern int cpp_GetValue(int a, int b);
    
    public App()
    {
        InitializeComponent();
    
        int x = 100;
        int y = 15;
        int z = 0;
        int z1 = 0;
        try
        {
            cpp_GetValue(5, 6);//XamCppDll.Shared.so
            z = subtract(x, y);//Dll1.dll
            z1 = add(x, y);//Dll1.dll
        }
        catch (System.Exception ex1)
        {
            Debug.WriteLine(ex1.Message);
        }
    
        Debug.WriteLine(" {0} - {1} = {2}", x, y, z);
        Debug.WriteLine(" {0} + {1} = {2}", x, y, z1);
    
        MainPage = new MainPage();
    
    }
    

    }

Project structure

project structure

Tutorials/codes referred

https://blog.xamarin.com/build-and-debug-c-libraries-in-xamarin-android-apps-with-visual-studio-2015/

https://blogs.msdn.microsoft.com/vcblog/2015/02/23/developing-xamarin-android-native-applications/

1
Isn't the problem XamCppDll.Shared.so souldn't it be XamCppDll.Shared.dll ?PilouPili
According to tutorial it would be .so I tried both .dll and .so ; they won't work. Neither Dll1.dll nor XamCppDll.Shared.so are found. It just gives not found exception with HResult - hex address , not mentioning .lib file for either approach.Morse
Isn't the DllNotFoundException more precise, which library is not found? In my memory it was more precise...PilouPili
@NPE getting precise error , I changed lib name on code and also tried do to sniffing by placing .so files but still same error.D/Mono (20164): DllImport attempting to load: 'libXamCppDll.so'. W/Mono (20164): DllImport unable to load library 'dlopen failed: library "/data/app/com.companyname.C__Test-1/lib/arm64/libXamCppDll.so" not found'.Morse
Are you sure all projets are compiled with the same target architecture (x86 or x64). Avoid any Any CPU lying aroud.PilouPili

1 Answers

3
votes

I figured this issue after spending so much time and testing.

In order load library the C++ should be packed as .so(Shared Object) extension within Android.

This file has to be packed and placed within .apk of the android.

  • Create and compile Xamarin C++ cross platform shared library project.
  • Compile Android specific linked project to get different architecture .so : x86 , x64 , ARM, ARM64 - these correspond to different ABIs too.
  • Link .so with android ABI

    1. Option 1 : create lib/abi_name folder and set .so file as AnroidNativeLibrary where abi_name can be

      • armeabi
      • armeabi-v7a
      • arm64-v8a
      • x86
      • x86_64
        Important note : In order to .so file to being copied to APK folder structure should be exactly as above. If device supported architecture is arm64-v8a but only x86 folder is created then .so file wont be available within APK and we still get DllNotFoundException.
    2. Option 2: Add .so file into android project with Build action AndroidNativeLibrary with <ABI> tag specifier. In Android .csproj file add as below.

      <ItemGroup>
      <AndroidNativeLibrary Include="path/to/libFile.so">
          <Abi>armeabi</Abi>
      </AndroidNativeLibrary>
      

I have added Github repository XamarinNDKSample for this if anyone wants working code.