Mono Android Monodroid Native Library DllNotFoundException - xamarin.android

I am attempting to get a Native C/C++ library working with Monodroid in the emulator, using DllImport. I am developing mainly in Windows/Visual Studio 2010.
I have built a native C/C++ library (ZeroMQ) using the Android NDK tools, to both x86 and armeabi platforms, using a Ubuntu virtual machine. Is this correct - x86 for emulator and armeabi for the real device? (This is certainly the case on the iPhone/MonoTouch - though in that case statically linked libzmq.a file and DllImport __Internal)
I have added the x86 version of libzmq.so to my MonoDroid project under the directory structure lib\x86\libzmq.so
When I first attempted to build/deploy to the simulator, I got an error 'cannot determine abi type', so I've added x86 to the AndroidNativeLibrary Include="lib\x86\libzmq.so"> project item group. This then deployed.
I have a DllImport for the function to call [DllImport("libzmq"
I've tried libzmq.so, lib/x86/libzmq, lib/x86/libzmq.so etc, but then I call the DllImported method (running in the emulator), I always get a DllNotFoundException.
Can anyone give me some direction?
EDIT: After reading another support answer which states that the emulator uses armeabi .so libraries, I have removed the x86/libzmq and added my lib/armeabi/libzmq.so as an AndroidNativeLibrary. I also removed the project file Abi entry, and indeed the project built and deployed fine.
However, I still get a DllNotFoundException when I try to call a DllImported function. Any ideas?
Many thanks

I don't have any immediate ideas why it isn't working for you; [DllImport("zmq")] should work.
The SanityTests sample exercises the DllImport attribute.
The DllImport: https://github.com/xamarin/monodroid-samples/blob/master/SanityTests/Hello.cs#L240
The Android.mk to build libfoo.so: https://github.com/xamarin/monodroid-samples/blob/master/SanityTests/jni/Android.mk
Building libfoo.so by calling ndk-build: https://github.com/xamarin/monodroid-samples/blob/master/SanityTests/SanityTests.csproj#L82
Including libfoo.so into the .apk: https://github.com/xamarin/monodroid-samples/blob/master/SanityTests/SanityTests.csproj#L96

(This is a repeat of my reply to your email in the ZeroMQ mailing list).
This error could be caused by using an incorrect platform target in your Mono project. I'm not sure if Mono/MonoDevelop supports this, but you probably need to create an ARM platform target, as opposed to x86/x64/Any CPU.
You would experience the same errors if you tried to do P/Invoke interop between an x64-targeted assembly with an x86 native library or vice-versa.
If you're using the clrzmq bindings for bridging Mono and libzmq, you will need to create a new platform target for ARM and rebuild the bindings. The solution only defines x86 and x64 platform targets currently.

Ok, I finally got it working! For whatever reason, ZeroMQ doesn't build correctly using the current/latest NDK r7. The instructions at http://www.zeromq.org/build:android use NDK r6. I also downloaded an old version of the NDK r5b (it was the easiest old version to find a download for), and rebuilt ZeroMQ using it. Result, it now works on emulator and phone!

Related

How to avoid "libraries attached to project that were compiled with kotlin/native compiler" error?

I am working on a Kotlin Multiplatform Mobile project. Tried adding in libraries for KMM, but I am getting
There are __ third-party libraries attached to the project that were compiled with an older Kotlin/Native compiler and can't be read in IDE.
The android project builds without problem so I was wondering if whether this error is only a warning and doesn't not affect the application at all?
Is there anyway to avoid this issue? How can I know if a library could be used for Kotlin Native?
Kotlin/Native doesn't guarantee binary compatability between versions - although as of 1.4 minor versions are experimentally binary backwards compatible. e.g. 1.4.10 should be compatible with 1.4.20 in the same project.
The easiest way to avoid the error is to ensure you're using KMM libraries with the same kotlin version as the kotlin version your project uses. Same goes for the IDE plugin.
Generally kotlin libraries by Jetbrains stay very up to date, as well as bigger libraries like SqlDelight. But smaller third party libraries can fall behind.
This issue is being actively worked on.

Is Mono framework or mono runtime part of the Xamarin IOS ipa package?

Basically, my question is if Xamarin IOS is statically compiled or compiled ahead of time (AOT), why do we need Mono Runtime within ipa?
May be I do not understand how does xamarin ios work in the ios devices?
Please can anybody shed some light?
When you compile any Xamarin platform application, the Mono C# (or F#)
compiler will run and will compile your C# and F# code into Microsoft
Intermediate Language (MSIL). If you are running a Xamarin.Android, a
Xamarin.Mac application, or even a Xamarin.iOS application on the
simulator, the .NET Common Language Runtime (CLR) compiles the MSIL
using a Just in Time (JIT) compiler. At runtime this is compiled into
a native code, which can run on the correct architecture for your
application.
However, there is a security restriction on iOS, set by Apple, which
disallows the execution of dynamically generated code on a device. To
ensure that we adhere to these safety protocols, Xamarin.iOS instead
uses an Ahead of Time (AOT) compiler to compile the managed code. This
produces a native iOS binary, optionally optimized with LLVM for
devices, that can be deployed on Appleā€™s ARM-based processor.
iOS App Architecture this link may be useful to you for more detail.
why do we need Mono Runtime within ipa?
The native ARM code that is generated by Xamarin.iOS (mtouch) AOT process depends upon the Mono runtime as the AOT process is not a transcoding compiler.
This dependency is mainly for the garbage collector but it also provides the runtime interface from the low level .Net/Mono framework calls to the iOS|tvOS|watchOS operating system.

How Does Dart AOT Work?

In my search for how Dart AOT works, I have not found many resources except this video. I would like to know how it is that code can be compiled down to native machine code, such as Android or iOS, when there exists different pieces of hardware that code needs to run on.
From what I understand, there are only descriptions of apps produced in Flutter. That description (written in Dart) is then compiled down to native machine code, but how? A program written in Swift is different from a program written in Kotlin.
A compiler creates the binary code from Dart source code.
For mobile applications the source code is compiled for multiple processors ARM, ARM64, x64 and for both platforms - Android and iOS. This means there are multiple resulting binary files for each supported processor and platform combination.
From what I understand, there are only descriptions of apps produced in Flutter.
Not sure what you mean by that. The concept of source code and compilation to a target platform is basically the same for each programming language.
JIT (Just in Time) compiles at runtime on-the-fly while AOT (Ahead of Time) compiles before the application is deployed and launched.
A program written in Swift is different from a program written in Kotlin.
Also not sure what you mean by that.
Swift can compile to native code and Java to Java bytecode. Swift is AoT while Java is JiT. The end result is always binary code for the target platform and CPU.

Unable to use System.XML.Linq

I am working on a project using Mono for Android. After reading a cross-platform document with Xamarin. I had my data layer in a separate project and was going to move it to my Mono for Android project and then link those files to my Mono Touch project, and one day perhaps a Windows Phone 8 project.
When I moved the code, I am now unable to compile because of the System.Xml.Linq reference. The reference shows in the Mono for Android project, but I am unable to use it. I thought aiming for Froyo may be the problem, but upgrading the project to Gingerbread or Ice Cream Sandwich didn't help.
Does anybody know what I am doing wrong? I am a seasoned .NET developer and am well aware of how references work in project, but this one has me stumped.
The project the original code was working on was targeting the Mono/.NET 4 framework
Is your reference to System.Xml.Linq pointing to the .Net version or the Mono version? The one for Mono will have Version 2.0.5.0.
Also, is the reference to System.Xml.Linq in a Android Class Library/Application or in a regular .Net Class library. If it is a .Net Class library, I would try referencing the library in your Android application as a compiled (dll) reference and not a project reference. It is not a perfect solution, but I have found that this works when I needed to reference libraries that I use across multiple solutions. The reference will generally work out fine, but if there is anything that is not supported in the Mono version, then it can cause issues.
Assuming you have your code in a class library, your best bet may be to create a Mono specific version of your library project. You can import and use the same class files, but just add some Conditional compilation symbols to have it compile properly for Mono. If you are not familiar with this, take a look at how Json.Net or ServiceStack manages code for multiple platforms.

using a C Dll and lib in obj c - ios

I have a C lib and dll file from windows application. No source code with me.
Is it possible to use that in an IOS application.
I have seen mixed responses and am confused.
If we have source code , i think we need to create dylib and then we can use the same after including relevant header file.
Please share any expert ideas to guide me in right direction.
Appreciate your help .
mia
Dynamic Libraries are not permitted on iOS to begin with, but above that, the DLL file format is not recognized by Darwin or the underlying XNU Kernel at all, as the binary format is different.
Windows APIs are not usable on the Darwin OS either (Both Mac OS X and iOS are wrappers around the basic Darwin OS). You will need to rewrite the code from the DLL to use the POSIX and/or Objective-C APIs and compile it as a static library to use it.
You need to get a iOS compatible library, no other way around it. There are several reasons:
iOS doesn't support DLLs as they are windows format, but moreover, you can't use any dynamic library on iOS, as Apple restricts it.
DLLs are usually for intel CPUs, while iOS devices have ARM CPUs.
Most dlls are calling windows APIs - are you sure this one's not?
No. If you all you have is a compiled binary DLL, there is no way to use it on iOS. Unless you happen to have an ARM DLL for the upcoming Windows 8, your DLL contains either x86 or x86-64 machine code (or maybe IA64 if you have a lot of money), which absolutely will not run on iOS devices, which are all ARM architectures. Plus many more reasons.
If you have the source code, you can recompile it for iOS, either directly into your app, as a static library that can be linked in with your app, or as a dynamic library as part of a framework. But in all cases, you need to recompile it from source code using the iOS compiler.
You are going to have to recompile it as a static library (.a file). Apple doesn't allow dynamic libraries except for their own frameworks (so you can't compile it as a dylib).

Resources