Поделиться через


Пример расширенного (ручного) реального мира

В этом примере используется библиотека POP из Facebook.

В этом разделе рассматривается более сложный подход к привязке, где мы будем использовать средство 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 (и помните, что 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. Мы знаем, что мы хотим создать пакет SDK iphoneos8.1 с arm64 архитектурой, и что файлы заголовков, о которых мы заботимся, находятся в build/Headers проверка pop git. Если вы посмотрите в 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.

Вы заметите, что мы передали -scope build/Headers аргумент в Objective Sharpie. Так как библиотеки C и Objective-C библиотеки должны #import или #include другие файлы заголовков, которые являются сведениями о реализации библиотеки, а не API, которые вы хотите привязать, -scope аргумент сообщает Objective Sharpie игнорировать любой API, который не определен в файле где-то в каталоге -scope .

-scope Аргумент часто необязателен для чисто реализованных библиотек, однако нет никакого вреда в явном предоставлении.

Совет

Если заголовки библиотеки импортируют все заголовки пакета SDK для iOS, например#import <Foundation.h>, необходимо задать область в противном случае Objective Sharpie создаст определения привязки для импортированного заголовка пакета SDK для iOS, что приведет к огромной привязке, которая, скорее всего, приведет к возникновению ошибок при компиляции проекта привязки.

Кроме того, мы указали -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.cs и Binding/StructsAndEnums.cs файлы.

Это базовый первый проход Objective Sharpie на привязке, и в некоторых случаях это может быть все, что вам нужно. Как указано выше, разработчику обычно потребуется вручную изменить созданные файлы после завершения Objective Sharpie, чтобы устранить все проблемы , которые не могут быть автоматически обработаны средством.

После завершения обновлений эти два файла теперь можно добавить в проект привязки в Visual Studio для Mac или передать непосредственно btouch в или bmac средства для создания окончательной привязки.

Подробное описание процесса привязки см. в наших инструкциях по завершению работы.