高度な (手動) 実際の例
この例では、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
を介したビルド時に、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 をバインドする準備ができました。 arm64
アーキテクチャを使用して SDK iphoneos8.1
用にビルドする必要があり、対象となるヘッダー ファイルが POP git チェックアウトの下の 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
するライブラリのメイン最上位のヘッダー ファイルであることがわかります。 このため、Objective Sharpie に POP.h
を渡すだけで済み、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 ライブラリは、バインドする API ではなくライブラリの実装の詳細である他のヘッダー ファイルを #import
または #include
する必要があるため、-scope
引数は、-scope
ディレクトリ内のどこかのファイルで定義されていない API を無視するように Objective Sharpie に指示します。
多くの場合、-scope
引数はクリーン実装されたライブラリでは省略可能ですが、明示的に指定しても問題はありません。
ヒント
ライブラリのヘッダーで #import <Foundation.h>
などの iOS SDK ヘッダーをインポートする場合、スコープを設定する必要があります。そうしないと、インポートされた iOS SDK ヘッダーのバインド定義が Objective Sharpie によって生成され、バインド プロジェクトのコンパイル時にエラーが発生する可能性が高い、膨大なバインディングとなります。
さらに、-c -Ibuild/headers
値を指定しました。 まず、-c
引数は、コマンド ライン引数の解釈を停止し、後続の引数を "clang コンパイラに直接" 渡すよう Objective Sharpie に指示します。 したがって、-Ibuild/Headers
は POP ヘッダーが存在する build/Headers
の下でインクルードを検索するように clang に指示する clang コンパイラ引数です。 この引数がないと、clang は、POP.h
が #import
しているファイルの場所を把握できません。 Objective Sharpie の使用に関するほとんどすべての "問題" は、詰まるところ、clang に何を渡すかを見つけ出すことに行き着きます。
バインドの完了
Objective Sharpie は、Binding/ApiDefinitions.cs
ファイルと Binding/StructsAndEnums.cs
ファイルを生成しました。
これらは、バインディングでの Objective Sharpie の基本的な最初のパスであり、場合によっては他は必要ありません。 ただし、前述のように、開発者は通常、Objective Sharpie が完了した後に生成されたファイルを手動で変更して、ツールで自動的に処理できなかった問題を修正する必要があります。
更新が完了すると、これら 2 つのファイルを Visual Studio for Mac のバインド プロジェクトに追加することも、直接 btouch
ツールまたは bmac
ツールに渡して最終的なバインドを生成することもできます。
バインド プロセスの詳細については、「完全なチュートリアルの手順」を参照してください。