Xamarin.Mac: 创建本机实例 class 时出错 "the native class hasn't been loaded",无法 dlopen
Xamarin.Mac: Error "the native class hasn't been loaded" when creating instance of native class, cannot dlopen
我正在尝试让一个非常简单的测试框架在 MonoMac 中工作/Xamarin.Mac。这是一个只有一种方法的 32 位框架,"run" 就是 returns NSString @"OK"。当我导入 dll 并创建 class 的实例时,它会在 运行 时抛出以下错误:
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
进行测试,我可以打开它。
- .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
时总是失败
Simple.dll 是用 sharpie 和 bmac 创建的,我认为最后一切顺利,但这是对它的描述: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
确保将框架设置为动态库:
现在文件的输出为:
file Simple.Framework/Versions/A/Simple
Simple.Framework/Versions/A/Simple: Mach-O dynamically linked shared library i386
我正在尝试让一个非常简单的测试框架在 MonoMac 中工作/Xamarin.Mac。这是一个只有一种方法的 32 位框架,"run" 就是 returns NSString @"OK"。当我导入 dll 并创建 class 的实例时,它会在 运行 时抛出以下错误:
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 进行测试,我可以打开它。
- .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
时总是失败Simple.dll 是用 sharpie 和 bmac 创建的,我认为最后一切顺利,但这是对它的描述: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
确保将框架设置为动态库:
现在文件的输出为:
file Simple.Framework/Versions/A/Simple
Simple.Framework/Versions/A/Simple: Mach-O dynamically linked shared library i386