Odkazování na nativní knihovny v Xamarin. iOS

Xamarin. iOS podporuje propojení s nativními knihovnami a knihovnami jazyka C Objective-C . Tento dokument popisuje, jak propojit nativní knihovny jazyka C s vaším projektem Xamarin. iOS. Informace o tom, jak to samé provést u Objective-C knihoven, najdete v našem Binding Objective-C Types dokumentu.

Vytváření univerzálních nativních knihoven (i386, ARMv7 a ARM64)

Často je žádoucí sestavit nativní knihovny pro každou z podporovaných platforem pro vývoj pro iOS (i386 pro simulátor a ARMv7/ARM64 pro samotná zařízení). Pokud už máte projekt Xcode pro vaši knihovnu, je to ve skutečnosti to jednoduché.

Chcete-li vytvořit verzi i386 vaší nativní knihovny, spusťte následující příkaz z terminálu:

/Developer/usr/bin/xcodebuild -project MyProject.xcodeproj -target MyLibrary -sdk iphonesimulator -arch i386 -configuration Release clean build

Výsledkem bude nativní Statická knihovna v rámci MyProject.xcodeproj/build/Release-iphonesimulator/ . Zkopírujte (nebo přesuňte) soubor archivu knihovny (libMyLibrary. a), aby se někde došlo bezpečný pro pozdější použití, a to tak, aby byl jedinečný název (například libMyLibrary-i386. a), aby nekoliduje s verzemi arm64 a ARMv7 stejné knihovny, které vytvoříte jako další.

Chcete-li vytvořit verzi ARM64 vaší nativní knihovny, spusťte následující příkaz:

/Developer/usr/bin/xcodebuild -project MyProject.xcodeproj -target MyLibrary -sdk iphoneos -arch arm64 -configuration Release clean build

Tentokrát bude sestavena vytvořená nativní knihovna v umístění MyProject.xcodeproj/build/Release-iphoneos/ . Znovu zkopírujte (nebo přesuňte) Tento soubor do bezpečného umístění, přejmenujte ho na něco jako libMyLibrary-arm64. a tak, aby nedošlo ke konfliktu.

Nyní Sestavte verzi ARMv7 knihovny:

/Developer/usr/bin/xcodebuild -project MyProject.xcodeproj -target MyLibrary -sdk iphoneos -arch armv7 -configuration Release clean build

Zkopírujte (nebo přesuňte) výsledný soubor knihovny do stejného umístění, kam jste přesunuli ostatní 2 verze knihovny, a přejmenujte ji na něco, jako je libMyLibrary-ARMv7. a.

Chcete-li vytvořit univerzální binární soubor, můžete použít lipo nástroj podobný tomuto:

lipo -create -output libMyLibrary.a libMyLibrary-i386.a libMyLibrary-arm64.a libMyLibrary-armv7.a

Vytvoří se tím libMyLibrary.a Univerzální knihovna (FAT), která bude vhodná pro použití pro všechny cíle vývoje iOS.

Chybějící požadovaná architektura i386

Pokud se vám does not implement methodSignatureForSelectordoes not implement doesNotRecognizeSelector při pokusu o použití Objective-C knihovny v simulátoru iOS zobrazuje výstup zprávy nebo, Knihovna pravděpodobně není zkompilována pro architekturu i386 (viz část does not implement methodSignatureForSelector výše).

K ověření architektury podporovaných určitou knihovnou použijte v terminálu následující příkaz:

lipo -info /full/path/to/libraryname.a

Kde /full/path/to/ je úplná cesta k spotřebované knihovně a libraryname.a je název příslušné knihovny.

Pokud máte zdroj do knihovny, budete ho muset zkompilovat a vytvořit také pro architekturu i386, pokud chcete otestovat aplikaci v simulátoru iOS.

Propojování knihovny

Všechny knihovny třetích stran, které využíváte, musí být staticky propojené s vaší aplikací.

Pokud jste chtěli staticky propojit knihovnu "libMyLibrary. a", kterou jste získali z Internetu nebo vytvořit pomocí Xcode, budete muset udělat několik věcí:

  • Přenesení knihovny do projektu
  • Konfigurace Xamarin. iOS pro propojení knihovny
  • Přístup k metodám z knihovny.

Pokud chcete knihovnu přenést do projektu, vyberte projekt v Průzkumníku řešení a stiskněte Command + Option + a. Přejděte na libMyLibrary. a a přidejte ho do projektu. po zobrazení výzvy sdělte Visual Studio pro Mac nebo Visual Studio, aby se zkopíroval do projektu. Po jeho přidání vyhledejte libFoo. a v projektu, klikněte na něj pravým tlačítkem a nastavte akci sestavení na žádná.

Chcete-li Konfigurovat Xamarin. iOS, abyprovedla propojení knihovny, v možnostech projektu pro finální spustitelný soubor (ne do samotné knihovny, ale konečný program), který je potřeba přidat do nadbytečného argumentu buildu iOS(tyto jsou součástí možností projektu gcc_flags), za kterým následuje řetězec, který obsahuje všechny nadbytečné knihovny, které jsou pro váš program nutné, například:

-gcc_flags "-L${ProjectDir} -lMylibrary -force_load ${ProjectDir}/libMyLibrary.a"

Výše uvedený příklad připojí libMyLibrary. a.

můžete použít -gcc_flags k určení libovolné sady argumentů příkazového řádku, které se mají předat GCC kompilátoru, který slouží k provedení konečného odkazu na spustitelný soubor. Například Tento příkazový řádek, odkazuje také na CFNetwork Framework:

-gcc_flags "-L${ProjectDir} -lMylibrary -lSystemLibrary -framework CFNetwork -force_load ${ProjectDir}/libMyLibrary.a"

Pokud vaše nativní knihovna obsahuje kód jazyka C++, musíte také předat příznak-příponu CXX ve vašich "dalších argumentech", aby mohl Xamarin. iOS použít správný kompilátor. V jazyce C++ by předchozí možnosti vypadaly takto:

-cxx -gcc_flags "-L${ProjectDir} -lMylibrary -lSystemLibrary -framework CFNetwork -force_load ${ProjectDir}/libMyLibrary.a"

Přístup k metodám jazyka C z jazyka C #

V systému iOS jsou k dispozici dva druhy nativních knihoven:

  • Sdílené knihovny, které jsou součástí operačního systému.

  • Statické knihovny dodávané s vaší aplikací.

Chcete-li získat přístup k metodám definovaným v jednom z těchto hodnot, použijte funkce nespravovaného volání mono , což je stejná technologie, jakou byste použili v .NET, což je zhruba:

  • Určení funkce jazyka C, kterou chcete vyvolat
  • Určení jeho signatury
  • Určení knihovny, ve které žije
  • Zapsat příslušnou deklaraci volání nespravovaného volání

Když použijete P/Invoke, musíte zadat cestu knihovny, se kterou propojujete. Pokud používáte sdílené knihovny iOS, můžete cestu buď nekódujte pevně, nebo můžete použít praktické konstanty, které jsme v naší části definovali Constants . Tyto konstanty by měly pokrývat sdílené knihovny pro iOS.

Například pokud jste chtěli vyvolat metodu UIRectFrameUsingBlendMode z knihovny UIKit společnosti Apple, která má tento podpis v jazyce C:

void UIRectFrameUsingBlendMode (CGRect rect, CGBlendMode mode);

Vaše deklarace P/Invoke by vypadala takto:

[DllImport (Constants.UIKitLibrary,EntryPoint="UIRectFrameUsingBlendMode")]
public extern static void RectFrameUsingBlendMode (RectangleF rect, CGBlendMode blendMode);

Konstanty. UIKitLibrary jsou pouze konstantou definované jako "/System/Library/Frameworks/UIKit.framework/UIKit", vstupní bod umožňuje volitelně zadat externí název (UIRectFramUsingBlendMode) při vystavení jiného názvu v jazyce C#, kratší RectFrameUsingBlendMode.

Přístup k Dylibsu v jazyce C

Pokud je potřeba ve vaší aplikaci Xamarin. iOS využívat DYLIB jazyka C, je nutné před voláním atributu použít trochu speciální instalaci DllImport .

Například pokud máme Animal.dylib s Animal_Version metodou, kterou budeme volat v naší aplikaci, musíme informovat Xamarin. iOS umístění knihovny, než se ji pokusíte spotřebovat.

Provedete to tak, že upravíte Main.CS soubor a nastavíte jeho vzhled jako na následující:

static void Main (string[] args)
{
    // Load Dylib
    MonoTouch.ObjCRuntime.Dlfcn.dlopen ("/full/path/to/Animal.dylib", 0);

    // Start application
    UIApplication.Main (args, null, "AppDelegate");
}

Kde /full/path/to/ je úplná cesta k DYLIB spotřebovaného. S tímto kódem můžeme následně připojit k Animal_Version metodě následujícím způsobem:

[DllImport("Animal.dylib", EntryPoint="Animal_Version")]
public static extern double AnimalLibraryVersion();

Statické knihovny

Vzhledem k tomu, že můžete použít pouze statické knihovny v systému iOS, neexistuje žádná externí sdílená knihovna, se kterou by bylo možné propojit, takže parametr Path v atributu DllImport musí použít speciální název __Internal (Všimněte si, že se na začátku názvu podíváme na znaky dvojitého podtržítka), a to na rozdíl od názvu cesty.

To vynutí, aby DllImport vyhledal symbol metody, na kterou odkazujete v aktuálním programu, místo aby se pokoušel načíst ze sdílené knihovny.