Mono Class as shared library? - linux

.Net class can be compiled into a shared library (.dll). Can a mono class be compiled into a shared library in linux (.so)? how?

.Net .dll files are not real, i.e. native, shared libraries. By default, Mono also produces and consumes .dll files, using the same assembly format as Microsoft .Net. Both runtimes generate native code from this intermediate format during runtime.
However, it is possible to perform Ahead-Of-Time (AOT) compilation and save the resulting .so file to disk (Microsoft .Net equivalent of this is the ngen.exe native image generation and cache). When you invoke Mono with the --aot flag, it will save the native code in form of a .so library and use it whenever the same file is loaded again. You probably also want to add the -O=all flag to enable all optimizations (some of them are disabled by default because they are costly to perform).
However, please bear in mind that the cached native library probably won't be usable for linking into native programs.

Related

Can I use mtouch to build a library?

I want to build a dll from all my package dependencies using mtouch. I have tried different options and failed.
Giving the root-assembly as my dll plus all packages gives me MT0052: No command specified
I think mtouch can not do that . From doc of Using mtouch to Bundle Xamarin.iOS Apps , you can see :
The process of turning a .NET executable into an application is mostly driven by the mtouch command, a tool that integrates many of the steps required to turn the application into a bundle. This tool is also used to launch your application in the simulator and to deploy the software to an actual iPhone or iPod Touch device.
It just transfers a existed .NET executable into an application ,can not help you bind library into an application .
You also can see the COMPILATION MODE doc of mtouch , there are four mode :
--abi=ABI
Comma-separated list of ABIs to target. Currently supported: armv6, armv6+llvm, armv7, armv7+llvm, armv7+llvm+thumb2, armv7s, armv7s+llvm, armv7s+llvm+thumb2. Fat binaries are automatically created if more than one ABI is targetted.
To use the LLVM optimizing compiler code generation backend instead of Mono's default code generation backend target one of the llvm ABIs. Build times take considerably longer for native code, but the generated code is shorter and performs better.
You may also instruct the LLVM code generator to produce ARM Thumb instructions by targetting one of the llvm+thumb2 targets. Thumb instructions produce more compact executables.
--cxx
Enables C++ support. This is required if you are linking with some third party libraries that use the C++ runtime. With this flag, mtouch uses the C++ compiler to drive the compilation process instead of the C compiler.
-sim=DIRECTORY
This compiles the program and assemblies passed on the command line into the specified directory for use with the iOS simulator. This generates a standalone program that is entirely driven by the C# or ECMA CIL code.
-dev=DIRECTORY
This compiles the program and assemblies passed on the command line into the specified directory for use on an iPod Touch, iPhone or iPad device. The target directory can be used as the contents of a .app directory This generates a standalone program that is entirely driven by the C# or ECMA CIL code.
mtouch not supports binding library , it just compiles a existed executable which already binded library .
By the way , if want to bind a third party library , official doc recommands you to use Binding iOS Libraries .

Shared library bundled in the apk is not found at runtime

I do some native Android development which involves OpenSSL.
I cross compile it for armeabi (32b) using the Android NDK stand-alone toolchains. I cross-compile the native C libraries, copy the OpenSSL/native library .so files inside of my libs/ folder, which is referenced by my gradle this way:
sourceSets {
main {
jniLibs.srcDir(file("libs/"))
}
}
Anyway, the end result is that my .apk looks like this:
- > classes.dex
- > lib/
-> armeabi/
-> libcrypto.so
-> libssl.so
-> libmynativelibrary.so
- > res/ (...)
- > resources.arsc
- > META-INF/ (...)
- > kotlin/ (...)
- > AndroidManifest.xml
The shared libraries are correct 32-bit ARM ELF files. I've been using this exact APK on an API level 24 device with great success (Android 7.0+).
The issue: When I switch to an API level 21 device (Android 5.1-, I suspect that I would have the same issue with Android 6.0), the program instantly crashes when loading libmynativelibrary.so.
Since libcrypto.so is a dependency of libmynativelibrary.so, the program attempts to load it. It actually works fine on API level 24+, but crashes on API level 23-. It's because the loaded library is not the one in my .apk, but the one in the system. And such libraries seem to not be available below API level 24.
My question: How do I explicitly tell Android to look for the library in the .apk file first instead of the regular system libraries directories?
Thanks in advance.
Before Nogut, the system libraries were not protected from user apps. The name collisions are problematic, they caused Google to invent a separate namespace for the C++ shared runtime library, which is part of Android NDK.
The OpenSSL libraries are also widely used beyond your control. They may get loaded into your process even before you have a chance to load your own libssl.
Therefore, the best choice would be to build OpenSSL as static libs, and have libmynativelibrary.so linked to it statically. This way you have a monolithic binary that does not depend on others.
If you cannot follow this course, you should build OpenSSL libraries with mangled names, e.g. libmyssl.so and libmycrypto.so. This may help to avoid the simple name clash with system libraries.
Even better, follow the example of NDK and provide a unique namespace to you SSL API.
Don't expect that loading the libraries explicitly from their unpacked location at ApplicationInfo.nativeLibraryDir will be a robust solution: as I hunted before, the system libraries may happen to get loaded into your address space before.
Note that before Lollipop, you have too manually load all non-system dependencies, and in the proper order.
Also, the new NDK has dropped armeabi , so consider switching to armeabi-v7a.

Mingw-w64, what's the purpose of libgcc_s_seh.dll?

Libraries built with Mingw-w64 require those dll:
libwinpthread-1.dll
libstdc++-6.dll
libgcc_s_seh-1.dll
I wonder what's up with that, what each dll does? Especially libgcc_s_seh, is that structured exception handling? I thought mingw couldn't work with seh.
Why mingw requires to always bring those dll with your exe?
I wonder if I'm just wasting my time by not just using visual studio as a windows compiler. It's so bloated though, 9 gb for installation.
Especially libgcc_s_seh, is that structured exception handling? I thought mingw couldn't work with seh.
Newer versions of GCC (4.8+ if I'm correct) should support SEH on MinGW.
I wonder what's up with that, what each dll does?
They provide the runtime and standard library.
libwinpthread: PThreads implementation on Windows (Threading)
libstdc++: C++ Standard Library (C/C++ library functions etc.)
libgcc_s_seh: Exception handling (SEH)
Why mingw requires to always bring those dll with your exe?
Because your program uses them. If you write a program without threads, standard library and exception and any OS interaction you wont need them.
These DLL's bring everything you need to run your program. Btw. this is not a MinGW only thing, and happens on other systems / compilers too. Often you just don't note this because the OS already ships the libraries, eg. MSVC libraries are very likely on a Windows machine. Dynamic linking always requires some sort of library files, that are .dll on Windows and .so on Linux.
If you have it available on your system use ldd <your application> to see what libraries are dynamically linked.
You can install these MinGW libraries into the system libraries or somewhere where the OS can find it. This enables your programs to use it and you no longer have to ship it with every application (what avoids duplication).
On the other side another option is to static link them. Unlike dynamic linking, you don't need any DLL; on the downside is a increase of you applications size (as now the three libraries are baked into the exe now).
I wonder if I'm just wasting my time by not just using visual studio as a windows compiler.
This depends on your situation. But probably my answer will give you some more insight.

Calling .dll in linux environment in c++

I have windows dynamic linked library which I want to access from Linux environment. I don't have the source code of that library, so I cannot build .so file.
Is there a way by using Winelib or any other library or tool for converting library file to .so file, so that I can call functions defined in that library?
There is no easy way to do it, because the DLL cannot run in Linux enviromnemt all by itself. It will probably rely on user32.dll msvcrt.dll and friends at runtime, so you'll have to provide those files as well.
You can use winelib, but it doesn't just convert a .dll to an .so. You'll have to link the whole project that wants to call the DLL against winelib, and include the DLL itself with your app at runtime. If you are trying to port a Windows app to Linux, winelib will be able to convert your makefile for you, but it's far from automatic for complex projects.

JNI code in linux shared lib

I have a c++ library ported to linux.
Now I'm adding a JNI code so I can add a java wrapper.
The question is:
Is adding JNI to the same lib will effect the c++ application of the users --> So might it become not working if java not installed ... etc (Because it links to some code in jni.h and other stuff)?
It won't affect the current library if you add JNI to your library. JNI are a collection of interfaces and callback that make your library can be used by JVM. Without JNI, your library can't be used from JVM.
Your library will grow up in size and more symbols be exported when you add JNI.
By adding JNI to your current library, it means your library can be used as a normal library meanwhile can be loaded from JVM.
You may wish to consider creating a JNI wrapper in C/C++ and statically link to your current library. That way your currently library will still work for C/C++ apps and your code will be easier to debug and maintain. If you choose this route, you may also want to look into enabling link-time optimization for your JNI wrapper. Alternatively you could also dynamically link the JNI wrapper and just put both libraries in /lib (or where ever is appropriate), but you will have a runtime dependency on that base library.

Resources