2012-04-07 59 views
2

我正在尝试为ZBar库编写MonoTouch绑定,并且卡住了ZBarSymbolSet类型。这乍看上去非常简单:将实现NSFastEnumeration协议的Obj-C类型绑定到MonoTouch

@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 

但开始了问题,当我开始寻找到怎样的标准.NET IEnumerable接口到NSFastEnumerator协议实现绑定。我甚至不知道从哪里开始。

回答

2

所以我没有找到一种自动的方式来指示btouch挂接NSFastEnumerable协议方法来为绑定类提供IEnumerable接口实现。相反,我采取了手动方法,并添加了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的功能是我在ZBarSymbolSet类绑定为幸运的是zbar和iPhone SDK作者暴露指针从C zbar和库中的基本结构的性质的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循环,那么当然MonoTouch可以自动挂钩它吗?

+2

我已经提交了一个关于此问题的增强bug:https://bugzilla.xamarin.com/show_bug.cgi?id=4391 – 2012-04-11 12:18:17

+0

任何机会你可以分享你的绑定和一个示例项目? – Rick 2012-12-20 20:03:05

+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 2012-12-20 22:13:52