我正在尝试绑定一些本机代码以便在MonoMac / Xamarin.Mac中使用,但我不确定我哪里出错了。我创建了一个简单的dylib来测试:
nativelibrary.h :
- (NSString *)echo:(NSString *)message;
我知道我的库很好,因为我引用它并在Objective-C / Cocoa应用程序中使用它。
接下来,我尝试使用parse.exe生成初始绑定文件:
mono parse.exe [path...]/nativelibrary.h
问题#1 根据Miguel的guide
,没有生成'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项目中,并指定'content'构建操作。我验证.dylib被复制到我的包的'Resources'目录。
我可以实例化我的绑定对象的实例没问题:
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
我在另一个question中看到,我们需要强制加载.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'
我做错了什么?
答案 0 :(得分:5)
经过很多的试验和错误后,我能够完成这项工作。两个变化:
在我的自制 gen.cs 文件中,接口名称需要与我的本机名称相匹配,即
nativelibrary.h
@interface nativelibrary : NSObject
- (NSString *)echo:(NSString *)message;
gen.cs
使用MonoMac.Foundation;
namespace ManagedConsumer
{
[BaseType (typeof (NSObject))]
interface nativelibrary
{
[Export ("echo:")]
string Echo(string message);
}
}
其次,我的本地库本身似乎有些东西意味着无法使用 dlopen 打开它。我认为问题是XCode'library'项目默认为x64,看起来只有x86可以工作。
我从命令行编译它,就像这样:
gcc -arch i386 -framework Cocoa -o nativelibrary.o -c [path...]/nativelibrary.m
然后建立我的图书馆:
libtool -dynamic -flat_namespace -lSystem -undefined suppress -macosx_version_min 10.6 -install_name $CURRENT_DIR/nativelibrary.dylib -o nativelibrary.dylib nativelibrary.o
它现在有效。