高级(手动)真实示例

此示例使用 Facebook 中的 POP 库

本部分介绍一种更高级的绑定方法,我们将使用 Apple 的 xcodebuild 工具首先生成 POP 项目,然后手动推断 Objective Sharpie 的输入。 这基本上涵盖了 Objective Sharpie 在上一部分中幕后所做的事情。

 $ git clone https://github.com/facebook/pop.git
Cloning into 'pop'...
   _(more git clone output)_

$ cd pop

由于 POP 库有一个 Xcode 项目 (pop.xcodeproj),因此我们可以仅使用 xcodebuild 来生成 POP。 此过程反过来可能会生成 Objective Sharpie 需要分析的头文件。 正因如此,在绑定之前生成非常重要。 通过 xcodebuild 生成时,请确保传递的 SDK 标识符和体系结构与你打算传递给 Objective Sharpie 的 SDK 标识符和体系结构相同(请记住,Objective Sharpie 3.0 通常可为你执行此操作!):

$ xcodebuild -sdk iphoneos9.0 -arch arm64

Build settings from command line:
    ARCHS = arm64
    SDKROOT = iphoneos8.1

=== BUILD TARGET pop OF PROJECT pop WITH THE DEFAULT CONFIGURATION (Release) ===

...

CpHeader pop/POPAnimationTracer.h build/Headers/POP/POPAnimationTracer.h
    cd /Users/aaron/src/sharpie/pop
    export PATH="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin:/Applications/Xcode.app/Contents/Developer/usr/bin:/Users/aaron/bin::/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/usr/local/git/bin:/Users/aaron/.rvm/bin"
    builtin-copy -exclude .DS_Store -exclude CVS -exclude .svn -exclude .git -exclude .hg -strip-debug-symbols -strip-tool /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/strip -resolve-src-symlinks /Users/aaron/src/sharpie/pop/pop/POPAnimationTracer.h /Users/aaron/src/sharpie/pop/build/Headers/POP

...

** BUILD SUCCEEDED **

控制台中将输出大量生成信息作为 xcodebuild 的一部分。 如上所示,我们可以看到运行了“CpHeader”目标,其中头文件被复制到生成输出目录。 通常情况就是这样,它使绑定变得更容易:作为本机库生成的一部分,头文件通常将复制到“公共”可用位置,从而更容易分析绑定。 在本例中,我们知道 POP 的头文件位于 build/Headers 目录中。

现在我们已准备好绑定 POP。 我们知道,我们要使用 iphoneos8.1 体系结构生成 SDK arm64,并且我们关心的头文件位于 POP git checkout 下的 build/Headers 中。 如果我们查看 build/Headers 目录,将会看到许多头文件:

$ ls build/Headers/POP/
POP.h                    POPAnimationTracer.h     POPDefines.h
POPAnimatableProperty.h  POPAnimator.h            POPGeometry.h
POPAnimation.h           POPAnimatorPrivate.h     POPLayerExtras.h
POPAnimationEvent.h      POPBasicAnimation.h      POPPropertyAnimation.h
POPAnimationExtras.h     POPCustomAnimation.h     POPSpringAnimation.h
POPAnimationPrivate.h    POPDecayAnimation.h

如果我们查看 POP.h,可以看到它是库的 #import 其他文件的主要顶级头文件。 因此,我们只需将 POP.h 传递给 Objective Sharpie,clang 就会在幕后完成剩下的工作:

$ sharpie bind -output Binding -sdk iphoneos8.1 \
    -scope build/Headers build/Headers/POP/POP.h \
    -c -Ibuild/Headers -arch arm64

Parsing Native Code...

Binding...
  [write] ApiDefinitions.cs
  [write] StructsAndEnums.cs

Binding Analysis:
  Automated binding is complete, but there are a few APIs which have
  been flagged with [Verify] attributes. While the entire binding
  should be audited for best API design practices, look more closely
  at APIs with the following Verify attribute hints:

  ConstantsInterfaceAssociation (1 instance):
    There's no fool-proof way to determine with which Objective-C
    interface an extern variable declaration may be associated.
    Instances of these are bound as [Field] properties in a partial
    interface into a near-by concrete interface to produce a more
    intuitive API, possibly eliminating the 'Constants' interface
    altogether.

  StronglyTypedNSArray (4 instances):
    A native NSArray* was bound as NSObject[]. It might be possible
    to more strongly type the array in the binding based on
    expectations set through API documentation (e.g. comments in the
    header file) or by examining the array contents through testing.
    For example, an NSArray* containing only NSNumber* instances can
    be bound as NSNumber[] instead of NSObject[].

  MethodToProperty (2 instances):
    An Objective-C method was bound as a C# property due to
    convention such as taking no parameters and returning a value (
    non-void return). Often methods like these should be bound as
    properties to surface a nicer API, but sometimes false-positives
    can occur and the binding should actually be a method.

  Once you have verified a Verify attribute, you should remove it
  from the binding source code. The presence of Verify attributes
  intentionally cause build failures.

  For more information about the Verify attribute hints above,
  consult the Objective Sharpie documentation by running 'sharpie
  docs' or visiting the following URL:

    http://xmn.io/sharpie-docs

Submitting usage data to Xamarin...
  Submitted - thank you for helping to improve Objective Sharpie!

Done.

你会注意到,我们向 Objective Sharpie 传递了一个 -scope build/Headers 参数。 由于 C 和 Objective-C 库必须 #import#include 其他头文件(这些头文件是库的实现细节,而不是你希望绑定的 API),因此 -scope 参数会告知 Objective Sharpie 忽略未在 -scope 目录某个位置的文件中定义的任何 API。

你会发现,对于干净实现的库而言,-scope 参数通常是可选的,但显式提供它并没有什么坏处。

提示

如果库的标头导入任何 iOS SDK 标头(例如 #import <Foundation.h>),则需要设置作用域,否则 Objective Sharpie 将为导入的 iOS SDK 标头生成绑定定义,从而导致巨大的绑定,在编译绑定项目时可能会生成错误。

此外,我们还指定了 -c -Ibuild/headers。 首先,-c 参数告知 Objective Sharpie 停止解释命令行参数,并将所有后续参数直接传递给 clang 编译器。 因此,-Ibuild/Headers 是一个 clang 编译器参数,指示 clang 在 build/Headers(这是 POP 标头所在的位置)下搜索要包含的内容。 如果没有此参数,clang 将不知道在何处找到 POP.h 正在 #import 的文件。 使用 Objective Sharpie 时几乎所有的“问题”都可以归结为弄清楚要传递给 clang 的内容

完成绑定

Objective Sharpie 现已生成 Binding/ApiDefinitions.csBinding/StructsAndEnums.cs 文件。

这些是 Objective Sharpie 在绑定时基本性的第一个周期,在某些情况下,你可能只需这个周期。 但是,如上所述,开发人员通常需要在 Objective Sharpie 完成后手动修改生成的文件,以修复工具无法自动处理的任何问题。

更新完成后,现在可以将这两个文件添加到 Visual Studio for Mac 中的绑定项目,或者直接传递给 btouchbmac 工具来生成最终绑定。

有关绑定过程的完整说明,请参阅完整演练说明