Compartir vía


Creación y consumo de marcos personalizados para plataformas similares a iOS

A partir de .NET 9, AOT nativo admite la publicación de bibliotecas de clases de .NET que no dependen de cargas de trabajo de iOS para plataformas similares a iOS. Esta compatibilidad le permite crear bibliotecas nativas independientes que se pueden consumir desde aplicaciones iOS, Mac Catalyst y tvOS.

Importante

Este enfoque no incluye la compatibilidad integrada con la interoperabilidad de Objective-C y es posible que se requieran adaptaciones de código adicionales (como serializar argumentos de tipo de referencia) para lograr la interoperabilidad.

Creación de bibliotecas compartidas

En esta sección se describen los pasos para crear un proyecto de biblioteca de clases de .NET simple con compatibilidad con NativeAOT y generar una biblioteca nativa para plataformas similares a iOS desde ella.

  1. Descarga del SDK de .NET 9

  2. Crear un proyecto de biblioteca de clases

    dotnet new classlib -n "MyNativeAOTLibrary"
    
  3. Agregue las siguientes propiedades al archivo de proyecto. MyNativeAOTLibrary.csproj

    <PublishAot>true</PublishAot>
    <PublishAotUsingRuntimePack>true</PublishAotUsingRuntimePack>
    
  4. Edite el MyNativeAOTLibrary/Class1.cs código fuente para exponer un método administrado para que se pueda hacer referencia desde el código nativo como aotsample_add. Por ejemplo:

    using System.Runtime.InteropServices;
    namespace NaotLib;
    
    public class Class1
    {
        [UnmanagedCallersOnly(EntryPoint = "aotsample_add")]
        public static int Add(int a, int b)
        {
            return a + b;
        }
    }
    
  5. Publique la biblioteca de clases y el destino de la plataforma similar a iOS deseada especificando el identificador en tiempo de ejecución adecuado (al que se hace referencia a continuación como <rid>):

    dotnet publish -r <rid> MyNativeAOTLibrary/MyNativeAOTLibrary.csproj
    

La finalización correcta del paso anterior genera un par de archivos: una biblioteca MyNativeAOTLibrary.dylib compartida y sus símbolos MyNativeAOTLibrary.dylib.dSYMde depuración, que se encuentran en: MyNativeAOTLibrary/bin/Release/net9.0/<rid>/publish/.

Nota:

Para crear marcos universales, es necesario publicar la biblioteca de clases para las arquitecturas y x64 para Arm64 una plataforma determinada. Esto significa que debe repetir el paso 5 con un identificador en tiempo de ejecución diferente. Por ejemplo, publicaría la biblioteca de clases con identificadores en maccatalyst-arm64 tiempo de ejecución y maccatalyst-x64 como requisito previo para empaquetar la biblioteca compartida en un marco universal personalizado de MacCatalyst.

Creación y consumo de un marco personalizado

Apple impone un requisito que las bibliotecas compartidas (.dylibs) deben empaquetarse en marcos para poder consumirse desde aplicaciones.

En esta sección se describen todos los pasos necesarios para lograr esto y un escenario sencillo de una aplicación iOS/MacCatalyst que consume una biblioteca o marco nativeAOT compartido.

Nota:

Los pasos descritos son solo para fines de demostración. Los requisitos reales pueden diferir en función del caso de uso exacto.

Empaquetar la biblioteca compartida en un marco de iOS personalizado

  1. Cree una carpeta de marco:

    mkdir MyNativeAOTLibrary.framework
    
  2. Ajustar comandos de carga:

    • LC_RPATH comando load

      install_name_tool -rpath @executable_path @executable_path/Frameworks MyNativeAOTLibrary/bin/Release/net9.0/ios-arm64/publish/MyNativeAOTLibrary.dylib
      
    • LC_ID_DYLIB comando load

      install_name_tool -id @rpath/MyNativeAOTLibrary.framework/MyNativeAOTLibrary MyNativeAOTLibrary/bin/Release/net9.0/ios-arm64/publish/MyNativeAOTLibrary.dylib
      
  3. Empaquete manualmente el archivo binario en un archivo universal:

    lipo -create MyNativeAOTLibrary/bin/Release/net9.0/ios-arm64/publish/MyNativeAOTLibrary.dylib -output MyNativeAOTLibrary.framework/MyNativeAOTLibrary
    
  4. Agregue un archivo de lista de propiedades al marco:

    • Cree un archivo Info.plist .
    touch MyNativeAOTLibrary.framework/Info.plist
    
    • Agregar el contenido del apéndice al archivo creado Info.plist

Después del paso final, la estructura del marco debe tener este aspecto:

MyNativeAOTLibrary.framework
    |_ MyNativeAOTLibrary
    |_ Info.plist

Empaquetar la biblioteca compartida en un marco universal de MacCatalyst personalizado

Los marcos universales requieren archivos binarios tanto para arquitectura x64 como para Arm64 . Por este motivo, debe publicar bibliotecas nativas destinadas a los siguientes IDENTIFICADORES de antemano: maccatalyst-arm64 y maccatalyst-x64.

  1. Cree una estructura de carpetas de marco:

    mkdir -p MyNativeAOTLibrary.framework/Versions/A/Resources
    ln -sfh Versions/Current/MyNativeAOTLibrary MyNativeAOTLibrary.framework/MyNativeAOTLibrary
    ln -sfh Versions/Current/Resources MyNativeAOTLibrary.framework/Resources
    ln -sfh A MyNativeAOTLibrary.framework/Versions/Current
    
  2. Ajustar comandos de carga:

    • LC_RPATH comando load

      install_name_tool -rpath @executable_path @executable_path/../Frameworks MyNativeAOTLibrary/bin/Release/net9.0/maccatalyst-arm64/publish/MyNativeAOTLibrary.dylib
      install_name_tool -rpath @executable_path @executable_path/../Frameworks MyNativeAOTLibrary/bin/Release/net9.0/maccatalyst-x64/publish/MyNativeAOTLibrary.dylib
      
    • LC_ID_DYLIB comando load

      install_name_tool -id @rpath/MyNativeAOTLibrary.framework/Versions/A/MyNativeAOTLibrary MyNativeAOTLibrary/bin/Release/net9.0/maccatalyst-arm64/publish/MyNativeAOTLibrary.dylib
      install_name_tool -id @rpath/MyNativeAOTLibrary.framework/Versions/A/MyNativeAOTLibrary MyNativeAOTLibrary/bin/Release/net9.0/maccatalyst-x64/publish/MyNativeAOTLibrary.dylib
      
  3. Empaquete manualmente el archivo binario en un archivo universal:

    lipo -create MyNativeAOTLibrary/bin/Release/net9.0/maccatalyst-arm64/publish/MyNativeAOTLibrary.dylib MyNativeAOTLibrary/bin/Release/net9.0/maccatalyst-x64/publish/MyNativeAOTLibrary.dylib -output MyNativeAOTLibrary.framework/Versions/A/MyNativeAOTLibrary
    
  4. Agregue un archivo de lista de propiedades al marco:

    • Cree un archivo Info.plist .
    touch MyNativeAOTLibrary.framework/Versions/A/Resources/Info.plist
    
    • Agregar el contenido del apéndice al archivo creado Info.plist

Después del paso final, la estructura del marco debe tener este aspecto:

MyNativeAOTLibrary.framework
    |_ MyNativeAOTLibrary -> Versions/Current/MyNativeAOTLibrary
    |_ Resources -> Versions/Current/Resources
    |_ Versions
        |_ A
        |   |_ Resources
        |   |   |_ Info.plist
        |   |_ MyNativeAOTLibrary
        |_ Current -> A

Consumo de marcos personalizados

  1. Abrir Xcode (en este ejemplo Xcode 16.0 se usa)

  2. Creación de un proyecto de App

  3. Elija el nombre de la aplicación (por ejemplo, MyiOSApp) y elija Objective-C como lenguaje de origen.

  4. Adición de una referencia al MyNativeAOTLibrary marco

    • En la MyiOSApp pestaña Destinos generales , en Marcos, Bibliotecas y contenido incrustado, seleccione + agregar MyNativeAOTLibrary como marco al que se hace referencia.
    • En el cuadro de diálogo, elija Agregar otros ->Agregar archivos y, a continuación, vaya a la ubicación de MyNativeAOTLibrary.framework y selecciónelo.
    • Una vez seleccionada, establezca Embed and Sign la opción para MyNativeAOTLibrary framework.

    Referencia de Xcode add framework

  5. Agregar MyNativeAOTLibrary.framework ubicación a la lista de rutas de búsqueda del marco en la pestaña Configuración de compilación

    Ruta de búsqueda de Xcode add framework

  6. Edite main.m llamando al método aotsample_add administrado expuesto e imprimiendo el resultado

    extern int aotsample_add(int a, int b);
    int main(int argc, char * argv[]) {
        ...
        NSLog(@"2 + 5 = %d", aotsample_add(2, 5));
        ...
    }
    
  7. Seleccione el dispositivo iOS físico y compile o ejecute la aplicación.

  8. Inspeccione los registros después de que la aplicación se haya iniciado correctamente. La aplicación debe imprimir: 2 + 5 = 7

Nota:

Para MacCatalyst, use los mismos pasos, excepto en el paso 7, donde el destino de ejecución debe establecerse como: Mac (Mac Catalyst).

Compilación de bibliotecas estáticas con NativeAOT para plataformas similares a iOS

Como se describe en la introducción a la creación de bibliotecas nativas, es mejor crear bibliotecas compartidas sobre las estáticas debido a varias limitaciones.

Sin embargo, si lo desea, puede compilar una biblioteca estática siguiendo los pasos para compilar uno compartido e incluir una propiedad adicional en el archivo de proyecto:

<NativeLib>Static</NativeLib>

Una vez publicado el proyecto, la biblioteca MyNativeAOTLibrary.a estática se puede encontrar en: MyNativeAOTLibrary/bin/Release/net9.0/<rid>/publish.

En este artículo no se explica cómo consumir la biblioteca estática y configurar el proyecto de consumidor.

Contenido de Info.plist del apéndice

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleName</key>
    <string>MyNativeAOTLibrary</string>
    <key>CFBundleIdentifier</key>
    <string>com.companyname.MyNativeAOTLibrary</string>
    <key>CFBundleVersion</key>
    <string>1.0</string>
    <key>CFBundleExecutable</key>
    <string>MyNativeAOTLibrary</string>
    <key>CFBundlePackageType</key>
    <string>FMWK</string>
</dict>
</plist>