c# - 将实现 NSFastEnumeration 协议(protocol)的 Obj-C 类型绑定(bind)到 MonoTouch

标签 c# objective-c xamarin.ios

我正在尝试为 ZBar 库编写 MonoTouch 绑定(bind),但陷入了 ZBarSymbolSet 类型。乍一看很简单:

@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 接口(interface)绑定(bind)到 NSFastEnumerator 协议(protocol)实现时,问题就开始了。我真的不知道从哪里开始。

最佳答案

所以我没有找到一种自动方法来指示 btouch 连接 NSFastEnumerable 协议(protocol)方法以在绑定(bind)类上提供 IEnumerable 接口(interface)实现。相反,我采用了手动方法,并添加了我自己的带有 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 函数的 InnerNativeSymbolSetHandle 是我绑定(bind)在 ZBarSymbolSet 类上的一个属性,幸运的是,ZBar iPhone SDK 作者公开了指向 C ZBar 库中的底层结构的指针:

// @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 函数,而是通过 Hook 到 NSFastEnumeration 协议(protocol)的 countByEnumerateWithState 函数。如果客观的话-c 可以使用 Objective-c for 循环以通用方式完成此操作,那么 MonoTouch 肯定也可以自动 Hook 吗?

关于c# - 将实现 NSFastEnumeration 协议(protocol)的 Obj-C 类型绑定(bind)到 MonoTouch,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10057343/

相关文章:

c# - 我们如何获得相对于窗体的位置?

ios - 如何同时支持 iOS 7 和 8 的 NSCalendar?

xamarin.ios - Xamarin.iOS 应用程序何时需要 Register 属性?

ios - Xamarin.iOS 应用程序项目应用程序无法识别 GoogleService-Info.plist

objective-c - 如何压缩和缩小 NSImage?

c# - NSURLSession 下载任务 - Xamarin iOS F#

c# - 这是使用 Xamarin Forms 和 SQLite 建立数据库连接的完美方式吗?

c# - Java只是没有跟上吗?

c# - 在 C# 中对数组中的字符串进行二进制搜索

ios - 设置框架时weakSelf