Using Xamaring with NDK

MichaelMelamudMichaelMelamud Michae MelamudUSMember ✭✭

Hi All,

I am new to Xamarin and to android development,and i am having issues on importing a library to a project , so i have a few questions :

  1. Can i Import a static library to the project? or i can use only a shared library (.so files) ?

  2. My library will be compiled under GCC with a toolchain called atollic ( it comes with an modified version of eclipse ), should it be a specific GCC toolchain? or it does not matter ?.

  3. How do i import the static library to the project? maybe there is any example that i can use ?

Best regards,
Michael

Posts

  • JonathanPryorJonathanPryor Jonathan Pryor USXamarin Team Xamurai

    \1. Can i Import a static library to the project? or i can use only a shared library (.so files) ?

    You can only package shared libraries (.so files) into a .apk.

    \2. My library will be compiled under GCC with a toolchain called atollic ( it comes with an modified version of eclipse ), should it be a specific GCC toolchain? or it does not matter ?.

    I believe that it won't matter, as long as your library conforms to the Android ARM EABI.

  • MichaelMelamudMichaelMelamud Michae Melamud USMember ✭✭

    Hi Jonathan ,

    Yes i just figured it out by myslef , so now i have a .so file . but now i am facing another issue :

    I have put my so file ( ie. test.so) in /lib/armeabi folder (using visual studio)
    I am trying to do [DllImport("test.so")] public extern static int GetCount();

    But on runtime it throws me dll not found exception , i looked at the following document :

    http://docs.xamarin.com/guides/android/advanced_topics/using_native_libraries

    but i could not understand how to use Path "sniffing" or Using a //AndroidNativeLibrary/Abi , can you please explain me how do i do that ? or maybe i can provide the full path to the library.

    Thanks
    Michael

  • JonathanPryorJonathanPryor Jonathan Pryor USXamarin Team Xamurai

    But on runtime it throws me dll not found exception

    Sanity Check #1: Is the library in your .apk?

    $ unzip -l path/to/your/app.apk | grep test.so
    

    If it's not in there, that's a problem, and "path sniffing" may be implicated.

    I don't think this is your problem; "path sniffing" checks the parent directory name to determine the ABI. If your native library is lib/armeabi/test.so, then the ABI will be detected as armeabi.

    Sanity check #2: was the library installed?

    $ adb shell ls -l /data/data/@YOUR_PACKAGE_NAME@/lib
    

    If your .so isn't present, that would explain the DllNotFoundException.

    I suspect this is actually the problem: your native library needs to conform to Linux convention, i.e. have a lib prefix and a .so suffix. A file named test.so does not have the appropriate prefix, and thus won't be installed. Try renaming it to libtest.so, and update your DllImport accordingly:

    [DllImport ("test")]
    public static extern int GetCount();
    

    Furthermore, things get very complicated when your .apk contains more than one ABI, and the default Debug packages contain armeabi, armeabi-v7a, and x86 runtimes. Unless your target device is armeabi (e.g. an emulator running Android v2.3), it is very likely that armeabi libraries will not be extracted on an armeabi-v7a device.

    If possible, I would suggest not supporting armeabi and instead support only armeabi-v7a. Otherwise, you will need to:

    1. Recompile your native library separately for each ABI that you wish to support. (The Android NDK ndk-build toolchain can help.)

    2. Copy your lib/armeabi/libtest.so file into a lib/armeabi-v7a/libtest.so file, and add lib/armeabi-v7a/libtest.so to your .csproj.

      Note: If your native library requires any amount of thread-safety, e.g. if it uses PThreads, it will break on multi-core devices.

  • MichaelMelamudMichaelMelamud Michae Melamud USMember ✭✭

    Hi Jonthan ,

    First of All adding lib to the file name did the trick , and it worked with a shared library written in C .

    But when trying to do DLLImport on a shared library written in C++ , suddenly i recive the DLL not found exception again? .

    Maybe you know the reason why? is it even possible to work with a c++ shared library ?

    Thanks
    Michael

  • MichaelMelamudMichaelMelamud Michae Melamud USMember ✭✭

    Hi Jonthan ,

    One more thing , when i change the name of the ( previously working c compiled shared library) from libtst.so to for example libtstc.so and change the DLLImport to [DllImport("tstc")] public extern static int GetCounter();

    It does not find the library anymore , again i only changed the name of the file , nothing else.

  • MichaelMelamudMichaelMelamud Michae Melamud USMember ✭✭

    Also see screenshot of my configuration :

  • MichaelMelamudMichaelMelamud Michae Melamud USMember ✭✭

    I pinpointed the problem and i understand why i am getting the DLL not found exception , my *.so file consists of many *.o files ,it somehow effects it,and causes the DLL not found exception , this library have many classes , but i am just want as a begining to try a simple function (GetCounter(), no class related).

    do you know mabye why does it happen (its compiled for armv7 so no problem there) , this is my compilation script for the matter :

    I compile it as a static library in the IDE , and the in the command line i make a shared library from it :

    gcc -shared C:\Users\Victor\Atollic\TrueSTUDIO\ARM_workspace\EmbeddedTTS-Android\Debug\src\TTS\AudioFormat.o C:\Users\Victor\Atollic\TrueSTUDIO\ARM_workspace\EmbeddedTTS-Android\Debug\src\TTS\dsp_v3.o C:\Users\Victor\Atollic\TrueSTUDIO\ARM_workspace\EmbeddedTTS-Android\Debug\src\TTS\DSPUnitImpl.o C:\Users\Victor\Atollic\TrueSTUDIO\ARM_workspace\EmbeddedTTS-Android\Debug\src\TTS\EmbeddedAudioSink.o C:\Users\Victor\Atollic\TrueSTUDIO\ARM_workspace\EmbeddedTTS-Android\Debug\src\TTS\EmbeddedConverter_SelectedUnitsToAudioElements.o C:\Users\Victor\Atollic\TrueSTUDIO\ARM_workspace\EmbeddedTTS-Android\Debug\src\TTS\EmbeddedConverterAcousticAudioElement.o C:\Users\Victor\Atollic\TrueSTUDIO\ARM_workspace\EmbeddedTTS-Android\Debug\src\TTS\EmbeddedConverterSilenceAudioElement.o C:\Users\Victor\Atollic\TrueSTUDIO\ARM_workspace\EmbeddedTTS-Android\Debug\src\TTS\EmbeddedDistributedConverterRemote.o C:\Users\Victor\Atollic\TrueSTUDIO\ARM_workspace\EmbeddedTTS-Android\Debug\src\TTS\EmbeddedSelectedUnits_Parser.o C:\Users\Victor\Atollic\TrueSTUDIO\ARM_workspace\EmbeddedTTS-Android\Debug\src\TTS\EmbeddedSplicer_v2.o C:\Users\Victor\Atollic\TrueSTUDIO\ARM_workspace\EmbeddedTTS-Android\Debug\src\TTS\EmbeddedSynthesizer_v3.o C:\Users\Victor\Atollic\TrueSTUDIO\ARM_workspace\EmbeddedTTS-Android\Debug\src\TTS\NaiveAudioChunkImpl.o C:\Users\Victor\Atollic\TrueSTUDIO\ARM_workspace\EmbeddedTTS-Android\Debug\src\Protobuf\ProtobufDecoder.o C:\Users\Victor\Atollic\TrueSTUDIO\ARM_workspace\EmbeddedTTS-Android\Debug\src\TTS\PSOLA.o C:\Users\Victor\Atollic\TrueSTUDIO\ARM_workspace\EmbeddedTTS-Android\Debug\src\TTS\SampleFormatterFactory.o C:\Users\Victor\Atollic\TrueSTUDIO\ARM_workspace\EmbeddedTTS-Android\Debug\src\TTS\scratch_buffer.o C:\Users\Victor\Atollic\TrueSTUDIO\ARM_workspace\EmbeddedTTS-Android\Debug\src\TTS\SplicedUnitImpl_v2.o C:\Users\Victor\Atollic\TrueSTUDIO\ARM_workspace\EmbeddedTTS-Android\Debug\src\TTS\SplitUnitImpl_v2.o C:\Users\Victor\Atollic\TrueSTUDIO\ARM_workspace\EmbeddedTTS-Android\Debug\src\TTS\WavFile.o C:\Users\Victor\Atollic\TrueSTUDIO\ARM_workspace\EmbeddedTTS-Android\Debug\src\functions.o -o C:\Users\Victor\Documents\Projects\AndroidTTS\lib\armeabi-v7a\libttsgcc.so>

    this is the DLL import :

    [DllImport("ttsgcc" , EntryPoint = "__Z10GetCounterv")] public extern static int GetCounter();

    any ideas ?
    Thanks

  • FZelleFZelle Frank Zehlius DEMember ✭✭✭

    Because of many problems with namemangeling and things you should never use a c++ function .
    Allways use a cdecl or extern "C" .

  • MichaelMelamudMichaelMelamud Michae Melamud USMember ✭✭

    Actually i found the problem but i dont know why it happens :

    case 1 :

    test.cpp

    int GetCounter()
    {
    int i = 123;

    return i;
    }

    This is works just fine in the project and i can use the function /

    case 2:

    test.cpp

    class foo
    {
    public :

       int GetVal()
        {
           return 123;
         }
    

    }

    int GetCounter()
    {
    foo *pFoo = new foo();
    return foo->GetVal();
    }

    when trying to execute this one , i am getting dll not found exception , i am guessing it somehow related to the class that i defined , any ideas on how to fix it ?

    Thanks

  • moljacmoljac Miljenko Cvjetko HRBeta ✭✭✭

    case 1 is pure c

    case 2 is c++ superset of c, so the names will be mangled, see what FZelle wrote.

    More info http://www.mono-project.com/Interop_with_Native_Libraries chapter "Invoking Unmanaged Code", so

    1. check the names with nm or objdump and set DllImport.EntryPoint
    2. make c++ function/method C extern
  • moljacmoljac Miljenko Cvjetko HRBeta ✭✭✭

    This link might be usefull to see how to expose c++ member functions (make those extern)
    http://www.parashift.com/c%2B%2B-faq-lite/cpp-objs-passed-to-c.html

  • MickelMickel Mick Man AUMember

    "Note: If your native library requires any amount of thread-safety, e.g. if it uses PThreads, it will break on multi-core devices."

    G'day,

    Is this still true of the latest Xamarin?

    Regards,
    Mickel

  • Ganesh.4229Ganesh.4229 Ganesh Vadlakonda USMember ✭✭

    Hi all,
    I have done demo with one function using .so file.
    I have tried with .so file integration. and performed the above all steps.

    But the function in native library(.so) is getting found but the Instead of return String the application is crashing and showing the fallowing log.

    [Mono] DllImport attempting to load: 'hello-jni'.
    [Mono] DllImport error loading library '/storage/emulated/0/Android/data/NDKDemo.NDKDemo/files/.override/libhello-jni': 'dlopen failed: library "/data/data/NDKDemo.NDKDemo/lib//storage/emulated/0/Android/data/NDKDemo.NDKDemo/files/.override/libhello-jni" not found'.
    [Mono] DllImport loaded library '/storage/emulated/0/Android/data/NDKDemo.NDKDemo/files/.override/libhello-jni.so'.
    [Mono] DllImport searching in: 'hello-jni' ('/storage/emulated/0/Android/data/NDKDemo.NDKDemo/files/.override/libhello-jni.so').
    [Mono] Searching for 'Java_com_example_ndkpoc_MainActivity_stringFromJNI'.
    [Mono] Probing 'Java_com_example_ndkpoc_MainActivity_stringFromJNI'.
    [Mono] Found as 'Java_com_example_ndkpoc_MainActivity_stringFromJNI'.
    [mono-rt] Stacktrace:
    [mono-rt]
    [mono-rt] at <0xffffffff>
    [mono-rt] at (wrapper managed-to-native) NDKDemo.MainActivity.Java_com_example_ndkpoc_MainActivity_stringFromJNI ()
    [mono-rt] at NDKDemo.MainActivity/<>c__DisplayClass1.b__0 (object,System.EventArgs) [0x00001] in c:\Users\gvadlakonda\Documents\Projects\NDKDemo\NDKDemo\MainActivity.cs:49
    [mono-rt] at Android.Views.View/IOnClickListenerImplementor.OnClick (Android.Views.View) [0x0000d] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.21-series/49a04b96/source/monodroid/src/Mono.Android/platforms/android-19/src/generated/Android.Views.View.cs:1873
    [mono-rt] at Android.Views.View/IOnClickListenerInvoker.n_OnClick_Landroid_view_View_ (intptr,intptr,intptr) [0x00011] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.21-series/49a04b96/source/monodroid/src/Mono.Android/platforms/android-19/src/generated/Android.Views.View.cs:1840
    [mono-rt] at (wrapper dynamic-method) object.bde75c13-f5c7-4bb1-ac5e-2a5913f6c82d (intptr,intptr,intptr)
    [mono-rt] at (wrapper native-to-managed) object.bde75c13-f5c7-4bb1-ac5e-2a5913f6c82d (intptr,intptr,intptr)
    [mono-rt]
    [mono-rt] =================================================================
    [mono-rt] Got a SIGSEGV while executing native code. This usually indicates
    [mono-rt] a fatal error in the mono runtime or one of the native libraries
    [mono-rt] used by your application.
    [mono-rt] =================================================================
    [mono-rt]
    [libc] Fatal signal 11 (SIGSEGV) at 0x02490751 (code=1), thread 21359 (NDKDemo.NDKDemo)

    Please let me know the solution and suggetions to solve the issue.

  • Ganesh.4229Ganesh.4229 Ganesh Vadlakonda USMember ✭✭

    Hi all,
    I have done demo with one function using .so file.
    I have tried with .so file integration. and performed the above all steps.

    But the function in native library(.so) is getting found but the Instead of return String the application is crashing and showing the fallowing log.

    [Mono] DllImport attempting to load: 'hello-jni'.
    [Mono] DllImport error loading library '/storage/emulated/0/Android/data/NDKDemo.NDKDemo/files/.override/libhello-jni': 'dlopen failed: library "/data/data/NDKDemo.NDKDemo/lib//storage/emulated/0/Android/data/NDKDemo.NDKDemo/files/.override/libhello-jni" not found'.
    [Mono] DllImport loaded library '/storage/emulated/0/Android/data/NDKDemo.NDKDemo/files/.override/libhello-jni.so'.
    [Mono] DllImport searching in: 'hello-jni' ('/storage/emulated/0/Android/data/NDKDemo.NDKDemo/files/.override/libhello-jni.so').
    [Mono] Searching for 'Java_com_example_ndkpoc_MainActivity_stringFromJNI'.
    [Mono] Probing 'Java_com_example_ndkpoc_MainActivity_stringFromJNI'.
    [Mono] Found as 'Java_com_example_ndkpoc_MainActivity_stringFromJNI'.
    [mono-rt] Stacktrace:
    [mono-rt]
    [mono-rt] at <0xffffffff>
    [mono-rt] at (wrapper managed-to-native) NDKDemo.MainActivity.Java_com_example_ndkpoc_MainActivity_stringFromJNI ()
    [mono-rt] at NDKDemo.MainActivity/<>c__DisplayClass1.b__0 (object,System.EventArgs) [0x00001] in c:\Users\gvadlakonda\Documents\Projects\NDKDemo\NDKDemo\MainActivity.cs:49
    [mono-rt] at Android.Views.View/IOnClickListenerImplementor.OnClick (Android.Views.View) [0x0000d] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.21-series/49a04b96/source/monodroid/src/Mono.Android/platforms/android-19/src/generated/Android.Views.View.cs:1873
    [mono-rt] at Android.Views.View/IOnClickListenerInvoker.n_OnClick_Landroid_view_View_ (intptr,intptr,intptr) [0x00011] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.21-series/49a04b96/source/monodroid/src/Mono.Android/platforms/android-19/src/generated/Android.Views.View.cs:1840
    [mono-rt] at (wrapper dynamic-method) object.bde75c13-f5c7-4bb1-ac5e-2a5913f6c82d (intptr,intptr,intptr)
    [mono-rt] at (wrapper native-to-managed) object.bde75c13-f5c7-4bb1-ac5e-2a5913f6c82d (intptr,intptr,intptr)
    [mono-rt]
    [mono-rt] =================================================================
    [mono-rt] Got a SIGSEGV while executing native code. This usually indicates
    [mono-rt] a fatal error in the mono runtime or one of the native libraries
    [mono-rt] used by your application.
    [mono-rt] =================================================================
    [mono-rt]
    [libc] Fatal signal 11 (SIGSEGV) at 0x02490751 (code=1), thread 21359 (NDKDemo.NDKDemo)

    Please let me know the solution and suggetions to solve the issue.

  • JoshuaSellsJoshuaSells Joshua Sells USUniversity

    I am having similar issues. I can create my own .so lib and call it using p-invoke just fine.

    However, when I link in 3rd party .so's to my own, I start getting the file not found loader error on my .so file. I assume there are problems finding the 3rd party libs to which mine links...?

    In either case (my own, single .so that works, or multiple .so's that crashes), the .so's are in the .apk, but I cannot find them on the device. Not sure where the .so's are being installed.

    My test device is running Android 4.2.1.

    Anyone have some insight? I'll even take wild guesses at this point. =/

  • FinnyFinny Fine Fitz GBMember

    Yeah, it's the same situation. On afternoon, i may read it carefully. Thanks for question.

  • JoshuaSellsJoshuaSells Joshua Sells USUniversity

    just wanted to update: I've read, and got confirmation from other android devs that native code in an APK can only load .so's on Android's "whitelist" which is only system components.

    This certainly fits the symptoms.

    I've heard rumor that there may be a way to manually load other .so's, but you have to load them in reverse order, or there may be some explicit c/c++ command to load the dependencies manually/explicitly in your native code.

    Any info would be helpful, thnx!

  • EmilsJonansEmilsJonans Emils Jonans USMember ✭✭

    So I have been trying to link Android C++ native library for two days now..... and after some trial and error I managed to figure stuff out.....

    So I'm posting this for other developers that rans into DLLNotFound exception issue....

    I was trying to link a C++ assembly that depended on another shared library like stlport_shared..... And worked nicely with our Java Android app..... So i compiled it adding some missing functionality and added it to our Xamarin Forms Android app and in properties set that it's AndroidNativeLibrary and that it's always copied to output dir. Same went to the libstlport_shared.so that the lib needed... Then i run the app and it crashed with DLLNotFoundException.....

    Then I started to comment stuff out from the C++ files till I had one extern "C" method inside.... Still nothing... Then I started to remove files that needs to be compiled.... still the same exception! So then I removed APP_STL := stlport_shared from the Application.mk file... and the exception was gone!

    So I uncommented all the stuff I commented out and replaced APP_STL := stlport_shared with APP_STL := stlport_static in the Application.mk file....

    And poof it works!

    Hope that this post helped someone and that someone didn't spend two days with this issue like me :smiley:

  • alaeddinechebbialaeddinechebbi ala eddine chebbi USMember

    Hello All ;
    It is the first time that i develop android using xamarin Studio .
    I have a problem after downloading Andrid Sdk and Ndk and while configuring the sdk location ..
    The path of Ndk file wasn't accepted .

    Thank you for helping me

  • alaeddinechebbialaeddinechebbi ala eddine chebbi USMember
    edited August 2016

    x

Sign In or Register to comment.