我正在尝试绑定一些本机代码以在 MonoMac / Xamarin.Mac 中使用,但我不确定我哪里出错了。我创建了一个简单的 dylib 来测试:
本机库.h:
- (NSString *)echo:(NSString *)message;
我知道我的库很好,因为我引用它并在 Objective-C / Cocoa 应用程序中使用它。
接下来,我尝试使用 parse.exe 生成初始绑定文件:
mono parse.exe [path...]/nativelibrary.h
问题 #1 没有按照 Miguel 的指南生成“gen.cs”文件
问题#2 Parse.exe 实际上确实向控制台输出了一些东西,尽管它缺少我唯一的方法?
[BaseType (typeof (NSObject))]
interface nativelibrary {
}
无论如何,我继续制作自己的 gen.cs 文件,手动填写缺少的方法:
gen.cs:
using MonoMac.Foundation;
namespace ManagedConsumer
{
[BaseType (typeof (NSObject))]
interface Binding
{
[Export ("echo:")]
string Echo(string message);
// I also tried like this:
// NSString Echo(NSString message);
}
}
接下来,我尝试使用 bmac.exe 创建绑定 DLL:
mono bmac.exe -o="dynamiclibrary.dll" -d="MONOMAC" -r="System.Drawing" -v [path].../gen.cs
这会吐出一个我在 MonoMac 项目中引用的 .dll。
最后,我将 .dylib 本身添加到我的 MonoMac 项目中,并指定“内容”构建操作。我确认 .dylib 已复制到我的包的“资源”目录。
我可以毫无问题地实例化我的绑定对象的实例:
Binding b = new Binding();
Console.WriteLine(b.ToString());
问题 3但是,尝试调用我的方法:
Binding b = new Binding();
var result = b.Echo((NSString)"Hello, world");
导致非托管崩溃:
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_PROTECTION_FAILURE at 0x00000000bf74bffc
我在另一个问题中看到,我们需要强制加载 .dylib。所以我尝试在调用Application.Init()之前将此行插入到我的main.cs中:
Dlfcn.dlopen ("nativelibrary.dylib", 0);
但是我遇到了同样的崩溃。由于对dlopen的调用返回 0 而不是有效指针,因此我认为问题在于加载我的动态库。我也尝试使用该属性:
[assembly:MonoMac.RequiredFramework("nativelibrary.dylib")]
但这只会让我:
System.Exception: Unable to load required framework: 'nativelibrary.dylib'
我究竟做错了什么?