4

ObjectiveC クラスを C# にバインドする問題

monotouch プロジェクトでは、MonoTouch で使用するために Objective-C 型をバインドする方法について説明しています。AdMob ライブラリではこれを実行できませんでした ( sabonrai dot wordpress dot com の monotouch-binding-for-admob ブログも参照してください。

そこで、可能な限り最小のテスト プロジェクトを作成することにしました。文字列を返すメソッドと整数を返すメソッドの 2 つの単純なメソッドを持つ単純な 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)
    {
    }
  }
}

この小さなプロジェクトは、2 つの Console.Writeline ステートメントなしで実行されます。Console.WriteLine ステートメントの 1 つが実行されるとすぐに、出力なしでクラッシュします。

テスト ケースを再現するのに十分な情報を提供しながら、できるだけ簡潔にしようとしました。この問題の解決に役立つ追加情報があれば、喜んで提供いたします。

なぜこれが期待どおりに機能しないのか、誰にも分かりますか? 最小限の 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 アプローチのいずれかが所定の手順から逸脱する場所を確認できませんが、両方とも失敗します!

本当に、私たちはここで必死に助けが必要です...

4

1 に答える 1

6

ネイティブ ライブラリの THUMB モードを無効にしていない可能性があります。iOS SDK 3.0 以降、Apple リンカは Thumb ライブラリをより大きなプロジェクトにリンクする際に問題を抱えています。

サム モードを無効にするには、Xcode でネイティブ ライブラリを開き、次の手順を実行します。

  1. プロジェクト -> プロジェクト設定の編集
  2. 「ビルド設定の検索」に「親指」と入力します
  3. チェックボックスをオフにします
  4. ネイティブ ライブラリを再構築します。
于 2010-11-23T21:13:36.793 に答える