2013-05-14 21 views
5

Próbuję połączyć bibliotekę statyczną (foo.a) - która zawiera kod C++ - w projekcie Xamarin.Android po directions znalezionym w dokumentach Xamarina. Ani "metoda wąchania ścieżki", ani "element Abi w pliku projektu" wydaje się działać.Xamarin.Android: Jak połączyć bibliotekę statyczną?

wykorzystujące Metodę uzyskać nieobsługiwany wyjątek, gdy próbuję zadzwonić do funkcji bibliotecznych:

I/mono(2591): [ERROR] FATAL UNHANDLED EXCEPTION: System.EntryPointNotFoundException: ... 

należy wspomnieć, że nie miałem problemy z połączeniem i wzywającą do tej biblioteki (zbudowany na ARMv7, armv7s) z moim projektem Xamarin.iOS przy użyciu "dodatkowych argumentów mtouch" -cxx opisanej w metodzie here. Wszystkie moje DLLImports są takie same na różnych platformach ...

[DllImport(Import.lib, CallingConvention=CallingConvention.Cdecl)] 
internal static extern IntPtr FooMethodName(args); 

Więc, czego mi brakuje?

FYI: Używam Xamarin Studio 4.0.5 (build 4) Xamarin.Android 4.6.4 (Business Edition)

+0

Może działać, jeśli DllImport ("__ Internal") – tofutim

Odpowiedz

7

uświadamiam sobie to pytanie jest ponad rok, ale ponieważ Niedawno miałem do zrób dokładnie to i uderz mnie w głowę w tym samym miejscu, i tak i tak pójdę ...

TL; DR: nie możesz połączyć bibliotek statycznych z Xamarinem dla Androida, możesz tylko łączyć dynamiczne biblioteki (.so)

Kroki:

  • Jeśli twoja biblioteka jest zapisana w C, możesz pominąć pierwszy krok. Ale jeśli twoja lib jest napisana w C++, musisz najpierw zadeklarować publicznie wyeksportowane funkcje jako funkcje C w swoim kodzie (tj. Musisz umieścić je wewnątrz bloku #extern "C" {}). Jeśli tego nie zrobisz, twoje nazwy funkcji zostaną poddane manglingowi nazw C++, a Xamarin nie będzie mógł ich znaleźć.
extern "C" 
{ 
    void my_function(bool someParameter); 
} 
  • Korzystanie z Android NDK, kompilowania biblioteki do biblioteki dołączanej dynamicznie (.so). Biblioteka statyczna (.a) będzie miała wartość , a nie. To tutaj uderzyłem się w głowę, ponieważ nie wynika to z dokumentacji. Dodając do zamieszania, na IOS jest to dokładnie naprzeciwko: możesz tam połączyć statyczne .a libs tylko (zgodnie z zasadami AppStore).
  • Zrób to dla każdej architektury procesora, która ma być obsługiwana (zazwyczaj, armeabi, armeabi-v7a i x86).
  • Odtąd zakładam, że masz zestaw bibliotek .so, po jednej dla każdej architektury procesora. Wszystkie biblioteki mają nazwę libX.so, gdzie X jest nazwą projektu twojej biblioteki. Na przykład. "libmylibrary.so".
  • W swoim projekcie Xamarin Android dodaj folder "libs" poniżej katalogu głównego projektu. (Możesz także użyć innej nazwy, jeśli chcesz)
  • Pod folderem "libs" utwórz trzy foldery potomne o nazwach "armeabi", "armeabi-v7a" i "x86". Skopiuj jeden z plików .so do każdego z tych folderów podrzędnych (ten odpowiadający tej samej architekturze procesora). Umożliwia to funkcję "wąchania ścieżki" Xamarin, która wybierze odpowiednią bibliotekę dla właściwej architektury procesora.
  • Dołącz trzy.więc pliki w projekcie, a dla każdego z nich należy ustawić właściwość „Budowanie akcji” do „AndroidNativeLibrary”
  • Teraz dodaj funkcje wpis jako metody statyczne do klasy Xamarin z właściwego dllimport atrybuty:
namespace MyApp 
{ 
    public static class MyLibrary 
    { 
     [DllImport("libmylibrary", EntryPoint = "my_function")] 
     public static extern void MyFunction(Boolean someParameter); 
    } 
} 
  • To wszystko. Powinieneś teraz móc wywołać MyLibrary.MyFunction() z twojego Xamarin C# kod
Powiązane problemy