Odwoływanie się do bibliotek natywnych na platformie Xamarin.iOS
Platforma Xamarin.iOS obsługuje łączenie zarówno z natywnymi bibliotekami języka C, jak i Objective-C bibliotekami. W tym dokumencie omówiono sposób łączenia natywnych bibliotek języka C z projektem platformy Xamarin.iOS. Aby uzyskać informacje na temat wykonywania tych samych czynności w przypadku Objective-C bibliotek, zobacz nasz dokument Typy powiązańObjective-C.
Tworzenie bibliotek uniwersalnych natywnych (i386, ARMv7 i ARM64)
Często pożądane jest utworzenie bibliotek natywnych dla każdej z obsługiwanych platform programowania dla systemu iOS (i386 dla symulatora i armv7/ARM64 dla samych urządzeń). Jeśli masz już projekt Xcode dla biblioteki, jest to naprawdę proste do zrobienia.
Aby skompilować wersję biblioteki natywnej i386, uruchom następujące polecenie w terminalu:
/Developer/usr/bin/xcodebuild -project MyProject.xcodeproj -target MyLibrary -sdk iphonesimulator -arch i386 -configuration Release clean build
Spowoduje to utworzenie natywnej biblioteki statycznej w obszarze MyProject.xcodeproj/build/Release-iphonesimulator/
. Skopiuj (lub przenieś) plik archiwum biblioteki (libMyLibrary.a) do bezpiecznego miejsca do późniejszego użycia, nadając mu unikatową nazwę (taką jak libMyLibrary-i386.a), aby nie starła się z wersjami arm64 i armv7 tej samej biblioteki, którą utworzysz dalej.
Aby skompilować wersję arm64 biblioteki natywnej, uruchom następujące polecenie:
/Developer/usr/bin/xcodebuild -project MyProject.xcodeproj -target MyLibrary -sdk iphoneos -arch arm64 -configuration Release clean build
Tym razem skompilowana biblioteka natywna będzie znajdować się w MyProject.xcodeproj/build/Release-iphoneos/
lokalizacji . Po raz kolejny skopiuj (lub przenieś) ten plik do bezpiecznej lokalizacji, zmieniając jego nazwę na podobną do libMyLibrary-arm64.a , tak aby nie zderzyła się.
Teraz skompiluj wersję biblioteki ARMv7:
/Developer/usr/bin/xcodebuild -project MyProject.xcodeproj -target MyLibrary -sdk iphoneos -arch armv7 -configuration Release clean build
Skopiuj (lub przenieś) wynikowy plik biblioteki do tej samej lokalizacji, w której przeniesiono pozostałe 2 wersje biblioteki, zmieniając jej nazwę na libMyLibrary-armv7.a.
Aby utworzyć uniwersalny plik binarny, możesz użyć lipo
narzędzia w następujący sposób:
lipo -create -output libMyLibrary.a libMyLibrary-i386.a libMyLibrary-arm64.a libMyLibrary-armv7.a
Spowoduje to utworzenie libMyLibrary.a
biblioteki uniwersalnej (tłuszczu), która będzie odpowiednia do użycia dla wszystkich celów programistycznych systemu iOS.
Brak wymaganej architektury i386
Jeśli otrzymujesz does not implement methodSignatureForSelector
komunikat lub does not implement doesNotRecognizeSelector
w danych wyjściowych środowiska uruchomieniowego podczas próby użycia Objective-C biblioteki w symulatorze systemu iOS, biblioteka prawdopodobnie nie została skompilowana dla architektury i386 (zobacz sekcję Tworzenie uniwersalnych bibliotek natywnych powyżej).
Aby sprawdzić architektury obsługiwane przez daną bibliotekę, użyj następującego polecenia w terminalu:
lipo -info /full/path/to/libraryname.a
Gdzie /full/path/to/
jest pełna ścieżka do używanej biblioteki i libraryname.a
jest nazwą danej biblioteki.
Jeśli masz źródło do biblioteki, musisz również skompilować i powiązać ją z architekturą i386, jeśli chcesz przetestować aplikację w symulatorze systemu iOS.
Łączenie biblioteki
Każda biblioteka innej firmy, z której korzystasz, musi być statycznie połączona z aplikacją.
Jeśli chcesz statycznie połączyć bibliotekę "libMyLibrary.a", która została uzyskana z Internetu lub skompilowana za pomocą programu Xcode, musisz wykonać kilka czynności:
- Przenoszenie biblioteki do projektu
- Konfigurowanie platformy Xamarin.iOS w celu połączenia biblioteki
- Uzyskaj dostęp do metod z biblioteki.
Aby przenieść bibliotekę do projektu, wybierz projekt z Eksploratora rozwiązań i naciśnij klawisze Command+Option+a. Przejdź do biblioteki LibMyLibrary.a i dodaj ją do projektu. Po wyświetleniu monitu poinformuj Visual Studio dla komputerów Mac lub Visual Studio, aby skopiować go do projektu. Po dodaniu znajdź plik libFoo.a w projekcie, kliknij go prawym przyciskiem myszy i ustaw opcję Akcja kompilacji na brak.
Aby skonfigurować platformę Xamarin.iOS, aby połączyć bibliotekę, w opcjach projektu dla końcowego pliku wykonywalnego (nie samej biblioteki, ale w ostatnim programie) należy dodać dodatkowy argument kompilacji systemu iOS (są to część opcji projektu) opcję "-gcc_flags", po której następuje cytowany ciąg zawierający wszystkie dodatkowe biblioteki wymagane dla programu, na przykład:
-gcc_flags "-L$(MSBuildProjectDirectory) -lMylibrary -force_load $(MSBuildProjectDirectory)/libMyLibrary.a"
Powyższy przykład spowoduje połączenie biblioteki LibMyLibrary.a
Możesz użyć -gcc_flags
polecenia , aby określić dowolny zestaw argumentów wiersza polecenia do przekazania do kompilatora GCC użytego do wykonania końcowego linku pliku wykonywalnego. Na przykład ten wiersz polecenia odwołuje się również do struktury CFNetwork:
-gcc_flags "-L$(MSBuildProjectDirectory) -lMylibrary -lSystemLibrary -framework CFNetwork -force_load $(MSBuildProjectDirectory)/libMyLibrary.a"
Jeśli biblioteka natywna zawiera kod języka C++, należy również przekazać flagę -cxx w "Dodatkowych argumentach", aby platforma Xamarin.iOS wiedziała, że używa poprawnego kompilatora. W przypadku języka C++ poprzednie opcje wyglądają następująco:
-cxx -gcc_flags "-L$(MSBuildProjectDirectory) -lMylibrary -lSystemLibrary -framework CFNetwork -force_load $(MSBuildProjectDirectory)/libMyLibrary.a"
Uzyskiwanie dostępu do metod języka C z języka C#
W systemie iOS są dostępne dwa rodzaje bibliotek natywnych:
Udostępnione biblioteki będące częścią systemu operacyjnego.
Biblioteki statyczne dostarczane z aplikacją.
Aby uzyskać dostęp do metod zdefiniowanych w jednej z tych metod, należy użyć funkcji P/Invoke mono, która jest tą samą technologią, której można użyć na platformie .NET, czyli mniej więcej:
- Określanie funkcji języka C, którą chcesz wywołać
- Określanie podpisu
- Określanie, w której bibliotece znajduje się
- Napisz odpowiednią deklarację P/Invoke
W przypadku używania funkcji P/Invoke należy określić ścieżkę biblioteki, z którą łączysz. W przypadku korzystania z bibliotek udostępnionych systemu iOS możesz zakodować ścieżkę na stałe lub użyć stałych wygody zdefiniowanych w naszym Constants
systemie , te stałe powinny obejmować biblioteki udostępnione systemu iOS.
Jeśli na przykład chcesz wywołać metodę UIRectFrameUsingBlendMode z biblioteki UIKit firmy Apple, która ma ten podpis w języku C:
void UIRectFrameUsingBlendMode (CGRect rect, CGBlendMode mode);
Deklaracja P/Invoke będzie wyglądać następująco:
[DllImport (Constants.UIKitLibrary,EntryPoint="UIRectFrameUsingBlendMode")]
public extern static void RectFrameUsingBlendMode (RectangleF rect, CGBlendMode blendMode);
Constants.UIKitLibrary jest tylko stałą zdefiniowaną jako "/System/Library/Frameworks/UIKit.framework/UIKit", program EntryPoint pozwala nam określić opcjonalnie nazwę zewnętrzną (UIRectFramFramIngBlendMode) podczas uwidaczniania innej nazwy w języku C#, krótszy element RectFrameUsingBlendMode.
Uzyskiwanie dostępu do bibliotekI Dylibów języka C
Jeśli potrzebujesz korzystać z biblioteki Dylib języka C w aplikacji platformy Xamarin.iOS, przed wywołaniem atrybutu DllImport
jest wymagana nieco dodatkowa konfiguracja.
Jeśli na przykład mamy metodę Animal.dylib
Animal_Version
, która będzie wywoływana w naszej aplikacji, musimy poinformować platformę Xamarin.iOS o lokalizacji biblioteki przed próbą jej użycia.
W tym celu zmodyfikuj Main.CS
plik i utwórz go w następujący sposób:
static void Main (string[] args)
{
// Load Dylib
MonoTouch.ObjCRuntime.Dlfcn.dlopen ("/full/path/to/Animal.dylib", 0);
// Start application
UIApplication.Main (args, null, "AppDelegate");
}
Gdzie /full/path/to/
to pełna ścieżka do używanej biblioteki Dylib. Za pomocą tego kodu możemy połączyć się z Animal_Version
metodą w następujący sposób:
[DllImport("Animal.dylib", EntryPoint="Animal_Version")]
public static extern double AnimalLibraryVersion();
Biblioteki statyczne
Ponieważ w systemie iOS można używać tylko bibliotek statycznych, nie ma zewnętrznej biblioteki udostępnionej do połączenia, więc parametr ścieżki w atrybucie DllImport musi używać nazwy __Internal
specjalnej (zwróć uwagę na znaki podwójnego podkreślenia na początku nazwy) w przeciwieństwie do nazwy ścieżki.
Wymusza to polecenie DllImport w celu wyszukania symbolu metody, do której odwołujesz się w bieżącym programie, zamiast próby załadowania go z biblioteki udostępnionej.