3

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?

dgw
  • 13,418
  • 11
  • 56
  • 54
Benny
  • 33
  • 1
  • 3

3 Answers3

4

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.

jstedfast
  • 35,744
  • 5
  • 97
  • 110
  • In the question you can see `/opt/mono-2.10/bin/gmcs /platform:x86 sharpCall.cs` which is an invocation of the mono compiler – David Heffernan Mar 28 '12 at 22:17
  • Right, but that's irrelevant because it doesn't change the behavior of a 64bit runtime to run as 32bit. – jstedfast Mar 28 '12 at 22:38
  • well that would mean every user with a 64-bit system, who wants to use my software, needs to install a 32-bit runtime. Thats ugly. How does it behave with .NET under 32-Bit Windows calling a native DLL? Would there be the same Problem? – Benny Mar 29 '12 at 10:08
  • it turned out that windows uses wow64 for that and mono does not :( – Benny Mar 29 '12 at 11:54
  • It would be far easier if you built your assembly for AnyCPU and distributed a 32bit and 64bit unmanaged library. – IanNorton Mar 29 '12 at 21:22
  • distributing the library as 32 and 64 bit would work in my simple example but in my real project the unmanaged code is "third party", not open source and only available as 32 bit :( – Benny Mar 30 '12 at 06:31
  • 1
    Unfortunately, there's no equivalent of wow64 on Linux. That's a Windows-only thing. – jstedfast Mar 30 '12 at 13:25
0

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.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Well thats what i thought, but i don't know how to run my program in 32 bit mode because the /platform:x86 switch does not seem to have any effect? I don't know how to do that. Compiling the native code in 64 bit mode is not an option because in a further step i want to access a third party library which is only available in 32 bit. – Benny Mar 28 '12 at 19:33
  • Not familiar with mono. According to docs `-platform:x86` is what you need, but you have tried that. – David Heffernan Mar 28 '12 at 19:42
0

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.

Security Hound
  • 2,577
  • 3
  • 25
  • 42