2012-04-07 11 views
2

ZBarライブラリのMonoTouchバインディングを書き込もうとしていて、ZBarSymbolSet型に固執しています。これは、一見とてもシンプルになります。MonoTouchにNSFastEnumerationプロトコルを実装するObj-C型をバインドする

@interface ZBarSymbolSet 
    : NSObject <NSFastEnumeration> 
{ 
    const zbar_symbol_set_t *set; 
    BOOL filterSymbols; 
} 

@property (readonly, nonatomic) int count; 
@property (readonly, nonatomic) const zbar_symbol_set_t *zbarSymbolSet; 
@property (nonatomic) BOOL filterSymbols; 

- (id) initWithSymbolSet: (const zbar_symbol_set_t*) set; 

@end 


@interface ZBarSymbol : NSObject 
... I've left out the ZBarSymbol members, all thats important is that the ZBarSymbolSet should be an IEnumerable<ZBarSymbol> 
@end 

しかし、私はNSFastEnumeratorプロトコルの実装に標準.NET IEnumerableインターフェースをバインドする方法を検討して始めたときに問題が始まりました。私は本当にどこから始めるべきかわからない。

答えて

2

私は、IEnumerableインターフェイス実装をバインディングクラスに提供するために、NSFastEnumerableプロトコルメソッドをフックアップするようにbtouchに指示する自動方法を見つけられませんでした。代わりに私は手動のアプローチを取って、IEnumerableの実装で私自身の部分クラスを追加しました。この中で私は実際には、このObj-CライブラリがラップしていたCライブラリに直接呼び出さなければなりませんでした!

public partial class ZBarSymbolSet : IEnumerable<ZBarSymbol> 
{ 
    public IEnumerator<ZBarSymbol> GetEnumerator() 
    { 
     IntPtr symbol; 
     if (FilterEnabled) 
      symbol = zbar_symbol_set_first_symbol(this.InnerNativeSymbolSetHandle); 
     else 
      symbol = zbar_symbol_set_first_unfiltered(this.InnerNativeSymbolSetHandle); 

     while (symbol != IntPtr.Zero) 
     { 
      yield return new ZBarSymbol(symbol,0); 
      symbol = zbar_symbol_next(symbol); 
     } 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 

    [DllImport("__Internal")] 
    private extern static IntPtr zbar_symbol_next(IntPtr zBarSymbol); 

    [DllImport("__Internal")] 
    private extern static IntPtr zbar_symbol_set_first_symbol(IntPtr zbarSymbolSet); 

    [DllImport("__Internal")] 
    private extern static IntPtr zbar_symbol_set_first_unfiltered(IntPtr zbarSymbolSet); 
} 

C関数たに私はとして幸いにもC ZBarライブラリからの根本的な構造体へのポインタを暴露ZBar iPhone SDKの著者ZBarSymbolSetクラスにバインドプロパティ渡すために上記で使用InnerNativeSymbolSetHandle

// @interface ZBarSymbolSet : NSObject <NSFastEnumeration> 
[BaseType (typeof(NSObject))] 
interface ZBarSymbolSet 
{ 
    // @property (readonly, nonatomic) int count; 
    [Export("count")] 
    int Count { get; } 

    // @property (readonly, nonatomic) const zbar_symbol_set_t *zbarSymbolSet; 
    [Export("zbarSymbolSet")] 
    IntPtr InnerNativeSymbolSetHandle{ get; } 

    // @property (nonatomic) BOOL filterSymbols; 
    [Export("filterSymbols")] 
    bool FilterEnabled { get; set; } 
} 

これは手動による解決方法です。
私はまだbtouchがこれを行うための自動方法があることを望んでいます(明らかにこれらのC関数ではなく、NSFastEnumerationプロトコルのcountByEnumeratingWithState関数へのフックを介して行います)。objective-cが目的関数-c for loopの場合、MonoTouchは自動的にそれにフックすることもできますか?

+2

私はこれに関する拡張バグを提出しました:https://bugzilla.xamarin.com/show_bug.cgi?id=4391 –

+0

あなたのバインディングとサンプルプロジェクトを共有できますか? – Rick

+0

@Rick既にありますhttp://sourceforge.net/tracker/?func=detail&aid=3515884&group_id=189236&atid=928517 サンプルプロジェクトは含まれていませんが、非常に薄いラッパーですObj-Cライブラリの周りにあるので、既存のZBar iOS SDKサンプルプロジェクトに従ってください:h ttp://zbar.sourceforge.net/iphone/sdkdoc/tutorial.html – Tyson

関連する問題