Xamarin.Mac:错误"本地类没有加载"在创建本机类的实例时,不能dlopen

时间:2015-04-21 20:56:40

标签: c# xcode monomac dlopen xamarin.mac

我想在MonoMac / Xamarin.Mac中使用一个非常简单的测试框架。它是一个只有一种方法的32位框架,"运行"只需返回NSString @" OK"。当我导入dll并创建该类的实例时,它会在运行时抛出以下错误:

Could not create an native instance of the type 'OPN200x.SimpleClass': the native class hasn't been loaded.
It is possible to ignore this condition by setting MonoMac.ObjCRuntime.Class.ThrowOnInitFailure to false.
  • 我用lipo进行了双重检查,二进制文件确实是32位。
  • 我'已经 试图将此框架导入并运行到常规Xcode项目中 它工作正常。
  • 我刚刚在MonoMac项目中导入了.dylib 测试,我可以dlopen它。
  • .framework中的文件不会dlopen。

这些是Main.cs的内容:

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using OPN200x;
using System.IO;
using MonoMac.Foundation;
using MonoMac.AppKit;
using MonoMac.ObjCRuntime;

namespace MacTest
{
    class MainClass
    {

        static void Main (string[] args)
        {
            var absolutePath = "/Users/UserName/Code/Xamarin/MacTest/MacTest/Frameworks/Simple.framework/Versions/A/Simple";
            if (!File.Exists (absolutePath)) {
                Console.Error.WriteLine ("File not found");
            } else {
                Console.WriteLine ("File Found");
            }

            var absolutePath2 = "/Users/UserName/Code/Xamarin/MacTest/MacTest/bin/Debug/MacTest.app/Contents/MonoBundle/libopn_driver.dylib";
            if (!File.Exists (absolutePath2)) {
                Console.Error.WriteLine ("File not found");
            } else {
                Console.WriteLine ("File Found");
            }

            var absolutePath3 = "/Users/UserName/Code/Xamarin/MacTest/MacTest/bin/Debug/MacTest.app/Contents/MonoBundle/Simple.framework/Versions/A/Simple";
            if (!File.Exists (absolutePath3)) {
                Console.Error.WriteLine ("File not found");
            } else {
                Console.WriteLine ("File Found");
            }

            if (Dlfcn.dlopen ("/Users/UserName/Code/Xamarin/MacTest/MacTest/bin/Debug/MacTest.app/Contents/MonoBundle/libopn_driver.dylib", 0) == IntPtr.Zero) {
                Console.Error.WriteLine("Unable to load libopn_driver.dylib"); // Does not get logged
            }

            Console.Error.WriteLine (System.Reflection.Assembly.GetExecutingAssembly ().Location);
            if (Dlfcn.dlopen("Simple.framework/Versions/A/Simple", 0) == IntPtr.Zero) 
            {
                Console.Error.WriteLine("Unable to load the dynamic library."); // Gets logged
            }

            if (Dlfcn.dlopen("/Users/UserName/Code/Xamarin/MacTest/MacTest/bin/Debug/MacTest.app/Contents/MonoBundle/Simple.framework/Versions/A/Simple", 2) == IntPtr.Zero) 
            {
                Console.Error.WriteLine("Unable to load the dynamic library."); // Gets logged
            }



            if (Dlfcn.dlopen("/Users/UserName/Code/Xamarin/MacTest/MacTest/Frameworks/Simple.framework/Versions/A/Simple", 2) == IntPtr.Zero) 
            {
                Console.Error.WriteLine("Unable to load the dynamic library."); // Gets logged
            }

            if (Dlfcn.dlopen("/Users/UserName/Code/Xamarin/MacTest/MacTest/Frameworks/Simple.framework/Simple", 2) == IntPtr.Zero) 
            {
                Console.Error.WriteLine("Unable to load the dynamic library."); // Gets logged
            }

            var simple = new SimpleClass (); // This line crashes
            var result = simple.Run;
            Console.WriteLine (result);

            NSApplication.Init ();
            NSApplication.Main (args);
        }
    }
}

它总是找到我检查过的文件,但只是dlopen并且总是因为Simple框架而不是libopn_driver.dylib而失败

使用sharpie和bmac创建了Simple.dll,我认为它最终还是可以的,但这里有对它的描述:Converting custom native MacOS X library to dll using MonoMac


进一步调查

我已经在每个无法加载程序集的地方添加了以下日志:

Console.Error.WriteLine (Dlfcn.dlerror ());

这给了我每个地方大致相同的错误:

    dlopen(/Users/UserName/Code/Xamarin/MacTest/MacTest/bin/Debug/MacTest.app/Contents/MonoBundle/Simple.framework/Versions/A/Simple, 2): no suitable image found.  Did find:
    /Users/UserName/Code/Xamarin/MacTest/MacTest/Frameworks/Simple.framework/Versions/A/Simple: unknown file type, first eight bytes: 0x21 0x3C 0x61 0x72 0x63 0x68 0x3E 0x0A
    /Users/UserName/Code/Xamarin/MacTest/MacTest/bin/Debug/MacTest.app/Contents/MonoBundle/Simple.framework/Versions/A/Simple: unknown file type, first eight bytes: 0x21 0x3C 0x61 0x72 0x63 0x68 0x3E 0x0A

我认为这意味着图像在某种程度上不兼容,但我不确切知道原因。我已经用文件测试了:

file Simple.Framework/Versions/A/Simple
Simple.Framework/Versions/A/Simple: current ar archive random library

胖子:

lipo Simple.Framework/Versions/A/Simple -info
input file Simple.Framework/Versions/A/Simple is not a fat file
Non-fat file: Simple.Framework/Versions/A/Simple is architecture: i386

乍一看这对我来说似乎没问题,最终的应用程序也是如此:

file MacTest
MacTest: Mach-O executable i386

MacOS Lucas$ lipo MacTest -i
Non-fat file: MacTest is architecture: i386

1 个答案:

答案 0 :(得分:0)

确保将框架设置为动态库:

enter image description here

现在文件的输出显示为:

file Simple.Framework/Versions/A/Simple
Simple.Framework/Versions/A/Simple: Mach-O dynamically linked shared library i386