将 ObjectiveC 类绑定到 C# 问题

发布于 2024-10-03 20:58:24 字数 3553 浏览 0 评论 0原文

将 ObjectiveC 类绑定到 C# 问题

monotouch 项目描述了如何绑定 Objective-C 类型以与 MonoTouch 一起使用。我们未能对 AdMob 库执行此操作(另请参阅位于 sabonrai dot 的 monotouch-binding-for-admob 博客 因此,

我们决定创建一个尽可能小的测试项目,其中包含两个简单的方法,一个返回字符串,一个返回整数,

是 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 ();
    }
}

然后使用以下命令创建一个 libTstLib.a 和一个 TstLib.dll 文件。 btouch 实用程序:

/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 项目相同。

我们的小项目使用标题 Binding_New_Objective-C_Types 下 monotouch dot net 中描述的 btouch 方法,而 MT_SampleAdMob 项目使用同一位置描述的“手动”方法。

这两种方法都在类似的问题上失败了。一旦调用类或实例方法,应用程序就会崩溃而没有任何输出。

我们不知道可以采取什么措施来查明这个问题并找到解决方案。 Monotouch 为许多 ObjC 类提供了 C# 绑定,因此它一定是可能的。我们仔细研究了上面引用的 MonoTouch 文档。我们看不出 MT_SampleAdMob 或 btouch 方法会在哪里偏离规定的程序,但两者都失败了!

所以说真的,我们迫切需要一些帮助......

Binding ObjectiveC Class to C# problem

The monotouch project describes how to bind Objective-C Types for use with MonoTouch. We failed to do this for the AdMob library (see also the monotouch-binding-for-admob blog at sabonrai dot wordpress dot com.

So we decided to create the smallest possible test project. We wrote a simple objc class with two simple methods, one that returns a string, and one that returns an integer.

Here's the TstLib.h:

#import <Cocoa/Cocoa.h>
@interface TstCls : NSObject {
}
- (NSString *) Version;
- (int) GimmeAnInt;
@end

and the TstLib.m file:

#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

We've got a little objc console project to validate this library. Here's the code:

#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);
}

So, let's define a binding file for the btouch utility.

using MonoTouch.Foundation;
namespace TstLib {
  [BaseType (typeof (NSObject))]
    interface TstCls {
      [Export ("Version")]
      string Version ();
      [Export ("GimmeAnInt")]
      int GimmeAnInt ();
    }
}

We then create a libTstLib.a and a TstLib.dll file with the btouch utility:

/Developer/MonoTouch/usr/bin/btouch -o TstLib.dll TstCls.cs

We now create a new Monotouch window based iphone app 'ApiTest', add a Lib directory with the libTstLib.a and the TstLib.dll files, add a reference to this TstLib.dll and integrate our TstLib into the 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)
    {
    }
  }
}

This little project runs without the two Console.Writeline statements. It crashes without any output as soon as one of the Console.WriteLine statements is executed.

We've tried to be as concise as possible, still providing enough info to recreate the test case. We're very willing to provide any additional info to help fix this.

Does anybody see why this does not work as expected? We've limited ourselves to the bare minimum to test whether we can provide and use a binding for a minimal ObjC class.

Unfortunately it fails. And it fails in the same way as the MT_SampleAdMob project described in the monotouch-binding-for-admob blog.

Our little project uses the btouch approach described at monotouch dot net under heading Binding_New_Objective-C_Types whereas the MT_SampleAdMob project uses the 'manual' approach described at the same location.

Both approaches fail in a similar matter. As soon as a class or instance method is called, the app just crashes without any output.

We've got no idea what can be done to pinpoint this problem and come to a solution. Monotouch provides c# bindings for many of the ObjC classes, so it must be possible. We've carefully studied the MonoTouch docs referenced above. We fail to see where either the MT_SampleAdMob or this btouch approach would deviate from the prescribed procedure, and yet both fail!

So really, we desperately need some help here...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

江南烟雨〆相思醉 2024-10-10 20:58:24

您可能没有禁用本机库的 THUMB 模式。自 iOS SDK 3.0 以来,Apple 链接器在将 Thumb 库链接到更大的项目中时遇到问题。

您可以通过在 Xcode 中打开本机库并执行以下操作来禁用拇指模式:

  1. 项目 ->编辑项目设置
  2. 在“在构建设置中搜索”中键入“thumb”
  3. 取消选中框
  4. 重新构建您的本机库。

You likely didn't disable THUMB mode for your native library. Ever since iOS SDK 3.0 the apple linker has problems linking Thumb libraries into larger projects.

You can disable thumb mode by opening your native library in Xcode and doing the following:

  1. Project -> Edit Project Settings
  2. Type "thumb" in "Search in Build Settings"
  3. Uncheck box
  4. Rebuild your native library.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文