Ejemplo real avanzado (manual)
En este ejemplo se usa la biblioteca POP de Facebook.
En esta sección, se aborda un enfoque más avanzado para el enlace, donde usaremos la herramienta xcodebuild
de Apple para compilar primero el proyecto POP y, a continuación, deducir manualmente la entrada para Objective Sharpie. Se explica básicamente lo que Objective Sharpie está haciendo en segundo plano en la sección anterior.
$ git clone https://github.com/facebook/pop.git
Cloning into 'pop'...
_(more git clone output)_
$ cd pop
Dado que la biblioteca POP tiene un proyecto de Xcode (pop.xcodeproj
), solo podemos usar xcodebuild
para compilar POP. Este proceso puede generar a su vez archivos de encabezado que Objective Sharpie puede necesitar analizar. Este es el motivo por el que la compilación anterior al enlace es importante. Al realizar la compilación a través de xcodebuild
, asegúrese de pasar el mismo identificador y la misma arquitectura del SDK que pretenda pasar a Objective Sharpie (y recuerde que Objective Sharpie 3.0 normalmente puede hacerlo automáticamente):
$ 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 **
Habrá una gran cantidad de resultados de información de compilación en la consola como parte de xcodebuild
. Como se muestra anteriormente, podemos ver que se ejecutó un destino "CpHeader" en el que se copiaron los archivos de encabezado en un directorio de salida de compilación. Este suele ser el caso y facilita mucho el enlace: como parte de la compilación de la biblioteca nativa, los archivos de encabezado a menudo se copian en una ubicación consumible "públicamente", lo que puede facilitar el análisis para el enlace. En ese caso, sabemos que los archivos de encabezado de POP están en el directorio build/Headers
.
Ya estamos listos para enlazar POP. Sabemos que queremos realizar una compilación para el SDK iphoneos8.1
con la arquitectura arm64
y que los archivos de encabezado que nos importan están en build/Headers
en la comprobación GIT de POP. Si observamos en el directorio build/Headers
, veremos una serie de archivos de encabezado:
$ 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
Si observamos en POP.h
, podremos ver que es el archivo de encabezado de nivel superior principal de la biblioteca el que #import
a otros archivos. Debido a esto, solo necesitamos pasar POP.h
a Objective Sharpie, y clang hará el resto en segundo plano:
$ 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.
Verá que hemos pasado un argumento -scope build/Headers
a Objective Sharpie. Dado que las bibliotecas de C y Objective-C deben #import
u #include
otros archivos de encabezado que sean detalles de implementación de la biblioteca y no de la API que quiere enlazar, el argumento -scope
indica a Objective Sharpie que omita cualquier API que no esté definida en un archivo en algún lugar del directorio -scope
.
Encontrará que el argumento -scope
suele ser opcional para las bibliotecas implementadas de forma limpia; sin embargo, no hay nada de malo en proporcionarlo explícitamente.
Sugerencia
Si los encabezados de la biblioteca importan los encabezados del SDK de iOS, por ejemplo #import <Foundation.h>
, tendrá que establecer el ámbito; de lo contrario, Objective Sharpie generará definiciones de enlace para el encabezado del SDK de iOS que se importó, lo que dará lugar a un enlace enorme que probablemente generará errores al compilar el proyecto de enlace.
Además, hemos especificado -c -Ibuild/headers
. En primer lugar, el argumento -c
indica a Objective Sharpie que deje de interpretar los argumentos de la línea de comandos y pase los argumentos subsiguientes directamente al compilador de clang. Por lo tanto, -Ibuild/Headers
es un argumento del compilador de clang que indica a este último que busque incusiones en build/Headers
, que es donde residen los encabezados POP. Sin este argumento, clang no sabría dónde localizar los archivos que POP.h
está #import
ando. Casi todos los "problemas" con el uso de Objective Sharpie se reducen a averiguar qué pasar a clang.
Finalización del enlace
Objective Sharpie ahora ha generado archivos Binding/ApiDefinitions.cs
y Binding/StructsAndEnums.cs
.
Corresponden al primer paso básico de Objective Sharpie en el enlace y, en algunos casos, podría ser todo lo que necesita. Sin embargo, como se indicó anteriormente, el desarrollador generalmente deberá modificar manualmente los archivos generados después de que Objective Sharpie acabe de solucionar cualquier problema que la herramienta no pueda gestionar automáticamente.
Una vez completadas las actualizaciones, estos dos archivos ahora se pueden agregar a un proyecto de enlace en Visual Studio para Mac o pasarse directamente a las herramientas btouch
o bmac
para generar el enlace final.
Para obtener una descripción exhaustiva del proceso de enlace, consulte nuestras instrucciones completas.