将 ObjectiveC 类绑定到 C# 问题
monotouch 项目描述了如何绑定 Objective-C 类型以与 MonoTouch 一起使用。我们未能为 AdMob 库执行此操作(另请参阅sabonrai dot wordpress dot com 上的 monotouch-binding-for-admob 博客。
所以我们决定创建尽可能小的测试项目。我们用两个简单的方法编写了一个简单的 objc 类,一个返回一个字符串,一个返回一个整数。
这是 TstLib.h:
#import <Cocoa/Cocoa.h>
@interface TstCls : NSObject {
}
- (NSString *) Version;
- (int) GimmeAnInt;
@end
和 TstLib.m 文件:
#import "TstCls.h"
@implementation TstCls
- (NSString *) Version {
return @"I ain't got a version, I'm a poor lonesome cowboy...";
}
- (int) GimmeAnInt {
return 110646;
}
@end
我们有一个小的 objc 控制台项目来验证这个库。这是代码:
#import <Cocoa/Cocoa.h>
#import "../TstLib/TstCls.h"
int main(int argc, char *argv[])
{
TstCls* tstCls = [[TstCls alloc] init];
NSLog(@"version = %@", [tstCls Version]);
NSLog(@"the int = %d", [tstCls GimmeAnInt]);
return NSApplicationMain(argc, (const char **) argv);
}
因此,让我们为 btouch 实用程序定义一个绑定文件。
using MonoTouch.Foundation;
namespace TstLib {
[BaseType (typeof (NSObject))]
interface TstCls {
[Export ("Version")]
string Version ();
[Export ("GimmeAnInt")]
int GimmeAnInt ();
}
}
然后我们使用 btouch 实用程序创建一个 libTstLib.a 和一个 TstLib.dll 文件:
/Developer/MonoTouch/usr/bin/btouch -o TstLib.dll TstCls.cs
我们现在创建一个新的基于 Monotouch 窗口的 iphone 应用程序“ApiTest”,添加一个包含 libTstLib.a 和 TstLib.dll 文件的 Lib 目录,添加对此 TstLib.dll 的引用并将我们的 TstLib 集成到 Main.cs 中:
using System;
using System.Collections.Generic;
using System.Linq;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using TstCls;
namespace ApiTest
{
// -gcc_flags "-L${ProjectDir}/Lib -lTstLib -ObjC"
// or
// -gcc_flags "-L${ProjectDir}/Lib -lTstLib -force_load ${ProjectDir}/Lib/libTstLib.a"
public class Application
{
static void Main (string[] args)
{
UIApplication.Main (args);
}
}
// The name AppDelegate is referenced in the MainWindow.xib file.
public partial class AppDelegate : UIApplicationDelegate
{
// This method is invoked when the application has loaded its UI and its ready to run
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
// If you have defined a view, add it here:
// window.AddSubview (navigationController.View);
TstLib.TstCls tstCls = new TstLib.TstCls ();
Console.WriteLine ("TstLib.TstCls.Version() -> '{0}'", tstCls.Version ());
Console.WriteLine ("TstLib.TstCls.GimmeAnInt() -> '{0}'", tstCls.GimmeAnInt ());
window.MakeKeyAndVisible ();
return true;
}
// This method is required in iPhoneOS 3.0
public override void OnActivated (UIApplication application)
{
}
}
}
这个小项目在没有两个 Console.Writeline 语句的情况下运行。一旦执行 Console.WriteLine 语句之一,它就会崩溃而没有任何输出。
我们试图尽可能简洁,仍然提供足够的信息来重新创建测试用例。我们非常愿意提供任何其他信息来帮助解决此问题。
有人明白为什么这不能按预期工作吗?我们将自己限制在最低限度,以测试我们是否可以为最小的 ObjC 类提供和使用绑定。
不幸的是它失败了。它以与 monotouch-binding-for-admob 博客中描述的 MT_SampleAdMob 项目相同的方式失败。
我们的小项目使用在 monotouch dot net 标题 Binding_New_Objective-C_Types 下描述的 btouch 方法,而 MT_SampleAdMob 项目使用在同一位置描述的“手动”方法。
这两种方法在类似的问题上都失败了。一旦调用了类或实例方法,应用程序就会崩溃而没有任何输出。
我们不知道可以做些什么来查明这个问题并找到解决方案。Monotouch 为许多 ObjC 类提供了 c# 绑定,因此它必须是可能的。我们仔细研究了上面引用的 MonoTouch 文档。我们看不到 MT_SampleAdMob 或这种 btouch 方法会偏离规定程序的地方,但两者都失败了!
所以真的,我们在这里迫切需要一些帮助......