【问题标题】:Mono interop: Loading 32bit shared library does not work on my 64bit system单声道互操作:加载 32 位共享库在我的 64 位系统上不起作用
【发布时间】:2012-03-28 18:57:12
【问题描述】:

在我的系统上运行一个简单的互操作示例时遇到问题。 我构建了一个简单的 32 位共享库,名为 libtest.so (c++)

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

我的系统: Ubuntu Linux 10.04 x86_64

Mono C# 编译器版本 2.4.4.0

此外,我还有一个使用我的共享库的示例 c# 程序:

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;
        }   
}

问题:加载库不起作用。

导出 MONO_LOG_LEVEL=debug 给我以下提示: Mono-INFO: DllImport error loading library './libtest.so: Wrong ELF-Class: ELFCLASS32'.

好吧,我猜 mono 在 64 位模式下运行我的程序,因此它不能调用 32 位共享库?如果我以 64 位模式(没有 -m32)构建共享库,一切正常!!

我的 Mono-Compiler 2.4.4。没有使用 /platform:x86 指定平台的选项,因此我安装了 2.10 版,但使用它也不起作用。

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

是否可以在 64 位系统上加载 32 位共享库?

【问题讨论】:

    标签: c# mono interop 64-bit


    【解决方案1】:

    问题是您的系统上安装了 64 位版本的 Mono,它只能 P/Invoke 到 64 位本机库,它不能 P/Invoke 到 32 位本机库。

    -platform:x86 标志用于 C#编译器,而不是运行时,并且不提示运行时使用 32 位内存空间。

    如果你想 P/Invoke 到 32 位原生库,你需要在你的 Ubuntu 系统上安装 32 位版本的 Mono。

    【讨论】:

    • 在问题中你可以看到/opt/mono-2.10/bin/gmcs /platform:x86 sharpCall.cs 这是对单编译器的调用
    • 对,但这无关紧要,因为它不会将 64 位运行时的行为更改为 32 位运行。
    • 这意味着每个拥有 64 位系统的用户想要使用我的软件,都需要安装 32 位运行时。那是丑陋的。在 32 位 Windows 下调用本机 DLL 的 .NET 表现如何?会有同样的问题吗?
    • 原来windows使用wow64,而mono没有:(
    • 不幸的是,Linux 上没有 wow64 的等价物。这是 Windows 独有的东西。
    【解决方案2】:

    您不能将 32 位模块加载到 64 位进程中。要么运行 32 位进程,要么将本机模块编译为 64 位模块。

    【讨论】:

    • 这就是我的想法,但我不知道如何在 32 位模式下运行我的程序,因为 /platform:x86 开关似乎没有任何效果?我不知道该怎么做。在 64 位模式下编译本机代码不是一种选择,因为在进一步的步骤中,我想访问仅在 32 位中可用的第三方库。
    • 不熟悉单声道。根据文档-platform:x86 是您需要的,但您已经尝试过了。
    【解决方案3】:

    是否有可能在 64 位上加载 32 位共享库 系统?

    是的,但前提是您将使用所述共享库的程序编译为 32 位进程。

    好吧,我猜 mono 在 64 位模式下运行我的程序,因此它 不能调用 32 位共享库?如果我在 64位模式(没有-m32)一切正常!!

    这当然会发生。只需使用 m32 标志编译程序,您应该没有问题。

    【讨论】:

    • @DavidHeffernan - 我确定有。
    猜你喜欢
    • 2021-12-22
    • 1970-01-01
    • 1970-01-01
    • 2011-09-05
    • 2010-12-14
    • 2013-08-29
    • 2011-12-18
    • 2012-07-26
    • 2011-07-07
    相关资源
    最近更新 更多