2013-05-14 74 views
5

我想鏈接一個靜態庫(foo.a) - 其中包含C++代碼 - 在Xamarin的文檔中找到的directions之後的Xamarin.Android項目中。 「路徑嗅探方法」和「項目文件中的Abi元素」方法都不起作用。使用Xamarin.Android:你如何鏈接靜態庫?

兩種方法,我得到未處理的異常,當我嘗試打電話到庫函數:

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

我要指出,我就不會有任何麻煩聯和調用到這個庫(內置對ARMv7,armv7s)與我的Xamarin.iOS項目使用「額外mtouch參數」-cxx方法描述here。我所有的DLLImport在不同平臺上都是一樣的...

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

那麼,我錯過了什麼?

FYI: 我使用Xamarin Studio的4.0.5(建4),Xamarin.Android 4.6.4(商務版)

+0

它可能工作,如果你的DllImport(「__內部」) – tofutim 2016-12-12 18:19:13

回答

7

我意識到這個問題是一歲,但因爲我最近不得不做到這一點,並在同一個點擊中我的頭,我會盡力去...

TL; DR:你不能將靜態庫與Xamarin for Android鏈接,你只能鏈接動態庫( .so)

步驟:

  • 如果您的圖書館是用C編寫的,則可以跳過第一步。但是如果你的lib是用C++編寫的,你必須首先在你的代碼中聲明你的公共導出函數爲C函數(即你必須把它們放在#extern「C」{}塊中)。如果你不這樣做,你的函數名將會受到C++名稱的影響,Xamarin將無法找到它們。
extern "C" 
{ 
    void my_function(bool someParameter); 
} 
  • 使用Android NDK,編譯庫動態鏈接庫(的.so)。靜態庫(.a)將不是做的。這是我的頭腦,因爲這從文檔中不太清楚。在IOS中,這是正好相反:您可以鏈接靜態.a庫只有那裏(根據AppStore策略)。
  • 爲你做這個希望支持每個處理器架構(通常,armeabi,armeabi-V7A和x86)
  • 從這裏開始,我假定你有一組的.so庫,每個處理器一個木構建築的。這些庫全部命名爲libX.so,其中X是庫的項目名稱。例如。 「libmylibrary.so」。
  • 在您的Xamarin Android項目中,在項目根目錄下添加一個文件夾「libs」。 (如果您願意,也可以使用其他名稱)
  • 在文件夾「libs」下面,分別創建三個子文件夾,分別命名爲「armeabi」,「armeabi-v7a」和「x86」。將其中一個.so文件複製到每個這些子文件夾(對應於相同處理器體系結構的文件夾)。這使Xamarin的「路徑嗅探」功能可以爲正確的處理器架構選擇正確的庫。
  • 包括三個。所以在你的項目,併爲每一個集合的「生成操作」屬性文件「AndroidNativeLibrary」
  • 現在添加錄入功能爲靜態方法與正確的DllImport一個Xamarin類屬性:
namespace MyApp 
{ 
    public static class MyLibrary 
    { 
     [DllImport("libmylibrary", EntryPoint = "my_function")] 
     public static extern void MyFunction(Boolean someParameter); 
    } 
} 
  • 就是這樣。您現在應該能夠從您的Xamarin的C#代碼調用MyLibrary.MyFunction()