Mono interop: Loading 32bit shared library does no

2019-02-14 22:58发布

问题:

i have a problem running a simple interop example on my system. I built a simple 32-bit shared library called libtest.so (c++)

g++ -c -fpic test.cpp -m32
g++ -shared -fpic -o libtest.so test.o -m32

My System: Ubuntu Linux 10.04 x86_64

Mono C# compiler version 2.4.4.0

In addition i have a sample c# program using my shared library:

using System;
using System.ComponentModel;
using System.Runtime.InteropServices;

public class Test
{
        [DllImport("libdl.so")] 
        static extern IntPtr dlopen(string filename, int flags); 

        [DllImport("libdl.so")] 
        static extern IntPtr dlclose(IntPtr handle);

        [DllImport ("./libtest.so")]
        private static extern void HelloWorld();

        [DllImport ("./libtest.so",EntryPoint="Test")]
        private static extern int Testl(int a,int b); 

        public static int Main(string[] args)
        {   
                IntPtr handle = dlopen("./libtest.so",2);
                if(handle == IntPtr.Zero)
                {   
                       Console.WriteLine("Error loading shared library");
                        return -1; 
                }   

                HelloWorld();
                int ret = Testl(116,1);
                Console.WriteLine("Result from shared-Librarry Call: " + ret);

                dlclose(handle);
                return 0;
        }   
}

The Problem: Loading the library does not work.

exporting MONO_LOG_LEVEL=debug gives me the following hint: Mono-INFO: DllImport error loading library './libtest.so: Wrong ELF-Class: ELFCLASS32'.

Well i guess mono runs my program in 64-bit mode and therefore it cannot call a 32-bit shared library? If i build the shared library in 64 bit mode (without -m32) everything works fine!!

My Mono-Compiler 2.4.4. does not have the option to specify the platform with /platform:x86 and therefore i installed version 2.10, but using it does not work either.

/opt/mono-2.10/bin/gmcs /platform:x86 sharpCall.cs

Is there a possibility to load 32-bit shared libraries on a 64-bit system?

回答1:

The problem is that you have a 64bit version of Mono installed on your system which can only P/Invoke into 64bit native libraries, it cannot P/Invoke into 32bit native libraries.

The -platform:x86 flag is meant for the C# compiler, not the runtime, and does not hint to the runtime to use a 32bit memory space.

You need to install the 32bit version of Mono on your Ubuntu system if you want to P/Invoke into 32bit native libraries.



回答2:

You cannot load a 32 bit module into a 64 bit process. Either run a 32 bit process, or compile your native module as a 64 bit module.



回答3:

Is there a possibility to load 32-bit shared libraries on a 64-bit system?

Yes, but only if you compile the program that uses said shared libraries into a 32-bit process.

Well i guess mono runs my program in 64-bit mode and therefore it cannot call a 32-bit shared library? If i build the shared library in 64 bit mode (without -m32) everything works fine!!

Of course this happen. Just compile the program with the m32 flag and you should have no problems.