Morse
Morse

Reputation: 9134

How to call C++ library code from Xamarin Forms project - DllNotFoundException

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?

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/

Upvotes: 5

Views: 4378

Answers (1)

Morse
Morse

Reputation: 9134

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.

Upvotes: 4

Related Questions