2012-03-28 7 views
3

Ich habe ein Problem mit einem einfachen Interop-Beispiel auf meinem System. Ich baute einen einfachen 32-Bit Shared Library genannt libtest.so (C++)Mono Interop: Laden 32bit shared library funktioniert nicht auf meinem 64bit System

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

Mein System: Ubuntu Linux 10.04 x86_64

Mono C# Compiler Version 2.4.4.0

Zusätzlich i Habe ein Beispiel C# -Programm mit meiner 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; 
     } 
} 

Das Problem: Laden der Bibliothek funktioniert nicht.

Exportieren MONO_LOG_LEVEL = Debug gibt mir den folgenden Hinweis: Mono-INFO: DllImport Fehler beim Laden der Bibliothek './libtest.so: Falsche ELF-Klasse: ELFCLASS32'.

Nun ich denke mono läuft mein Programm im 64-Bit-Modus und kann daher keine 32-Bit-Shared-Library aufrufen? Wenn ich die Shared Library im 64-Bit-Modus (ohne -m32) erstelle, funktioniert alles einwandfrei !!

Mein Mono-Compiler 2.4.4. hat nicht die Option, die Plattform mit/platform: x86 anzugeben, und daher habe ich Version 2.10 installiert, aber es funktioniert auch nicht.

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

Gibt es eine Möglichkeit, 32-Bit-Shared-Libraries auf einem 64-Bit-System zu laden?

Antwort

3

Das Problem ist, dass Sie eine 64-Bit-Version von Mono auf Ihrem System installiert haben, die P nur kann/Invoke in 64-Bit-native Bibliotheken, es nicht P/Invoke in 32bit native Bibliotheken.

Das -platform: x86-Flag ist für den C# Compiler, nicht die Laufzeit gedacht, und weist nicht auf die Laufzeit einen 32bit Speicherplatz zu verwenden.

Sie müssen die 32-Bit-Version von Mono auf Ihrem Ubuntu-System installieren, wenn Sie in nativen 32-Bit-Bibliotheken P/Invoke durchführen möchten.

+0

In der Frage können Sie '/opt/mono-2.10/bin/gmcs/platform: x86 sharpCall.cs' sehen, was ein Aufruf des Mono-Compilers ist. –

+0

Richtig, aber das ist irrelevant, weil es das Verhalten von a nicht ändert 64-Bit-Laufzeit, um als 32bit zu laufen. – jstedfast

+0

Nun, das würde bedeuten, dass jeder Benutzer mit einem 64-Bit-System, der meine Software verwenden möchte, eine 32-Bit-Laufzeitumgebung installieren muss. Das ist hässlich. Wie verhält es sich mit .NET unter 32-Bit Windows beim Aufruf einer nativen DLL? Würde es das gleiche Problem geben? – Benny

0

Sie können ein 32-Bit-Modul nicht in einen 64-Bit-Prozess laden. Führen Sie entweder einen 32-Bit-Prozess aus oder kompilieren Sie Ihr natives Modul als 64-Bit-Modul.

+0

Nun, das ist, was ich dachte, aber ich weiß nicht, wie ich mein Programm im 32-Bit-Modus ausführen, weil der/plattform: x86-Schalter scheint keine Wirkung zu haben? Ich weiß nicht, wie ich das machen soll. Das Kompilieren des systemeigenen Codes im 64-Bit-Modus ist keine Option, da ich in einem weiteren Schritt auf eine Bibliothek von Drittanbietern zugreifen möchte, die nur in 32-Bit verfügbar ist. – Benny

+0

Nicht vertraut mit Mono. Laut Dokumentation '-Plattform: x86' ist das, was Sie brauchen, aber Sie haben das ausprobiert. –

0

Gibt es eine Möglichkeit, 32-Bit-Shared Libraries auf einem 64-Bit-System zu laden?

Ja, aber nur, wenn Sie das Programm kompilieren, das diese gemeinsam genutzten Bibliotheken in einem 32-Bit-Prozess verwendet.

Nun, ich denke mono läuft mein Programm im 64-Bit-Modus und daher kann eine 32-Bit-Shared-Library nicht aufrufen? Wenn ich die shared library in 64-Bit-Modus (ohne -M32) baue, funktioniert alles gut !!

Natürlich geschieht dies. Kompilieren Sie einfach das Programm mit dem m32-Flag und Sie sollten keine Probleme haben.

+0

Hat Mono eine M32-Flagge? –

+0

@DavidHeffernan - Ich bin mir sicher, dass es da ist. –

Verwandte Themen