我有一个分为两个部分的项目。第一部分是一组包装本地.dll或.so库的C#绑定。这将产生一个NugGet包,然后由另一个项目使用。
[另一个是使用这些C#绑定的Xamarin Forms项目。我的Xamarin项目的UWP部分在找到NuGet包中的本机库时没有问题。但是,Android项目找不到它。确实,打开APK会显示本地.so文件永远不会进入。
我正在使用NuGet's mechanism for including arch-specific libraries,方法是在/runtimes/platform-arch/native/
文件夹中包含每个特定于平台的.dll-or-.so。对于绑定项目,我的文件夹结构如下所示:
...并且我可以确认文件夹结构已正确保存在生成的.nupkg
文件中,在包的根目录下有一个runtimes
文件夹,并在其下面有一系列子文件夹。
我使用新的内置.csproj机制生成NuGet包,没有任何.targets文件。我的NuGet项目的csproj看起来像这样:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<Version>1.0.5.1</Version>
<Company />
<Product />
</PropertyGroup>
<ItemGroup>
<Content Include="runtimes\**" PackagePath="runtimes">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="OneOf" Version="2.1.150" />
</ItemGroup>
</Project>
我的项目的第二部分是Xamarin Forms项目,我将NuGet包导入到项目的.NET Standard跨平台部分。
构建UWP项目时,特定于平台的.dll
已正确复制到我的.appx
文件的根目录,并且我可以成功P / Invoke。 (我注意到,仅当我在x64配置中构建并且在x64机器上编译时,此方法才有效。)但是,在构建Android项目时,.so
Android库不会发生这种情况。
整个依赖链看起来像这样:
-------------NuGet Package----------
| - native_lib.so |
| - (other runtime dlls, etc) |
------------------------------------
^
|
-----Xamarin.Forms Core Project-----
| - Imports NuGet |
------------------------------------
^
|
-------Xamarin Android Project------
| - Imports Xamarin Forms Core Proj|
| - Produces APK |
------------------------------------
这似乎不是命名问题,试图将绑定项目中的native_lib.so
重命名为libnative_lib.so
无效。
我错过了一步,还是NuGet根本不理解Xamarin.Android项目需要将本地库复制到APK中?
NuGet项目的源代码:https://github.com/pingzing/scannitsharp使用NuGet的Xamarin Forms项目的源代码:https://github.com/pingzing/scannitNuGet软件包:https://www.nuget.org/packages/ScannitSharp/1.0.5.1
通常来说,您需要在Q中共享更多信息,例如代码和打包文件。
NuGet是否根本不了解Xamarin.Android项目需要将本地库复制到APK中?
是的。您需要以MSBuild将文件包含在最终APK中的方式打包NuGet。
对于Android,这是通过AndroidNativeLibrary
完成的>>
以及此处的工作示例https://github.com/mfkl/libvlc-nuget/blob/master/build/VideoLAN.LibVLC.Android.targets
[我注意到,只有在x64配置中构建并且正在x64机器上编译时,此方法才有效。
您可能需要修改目标文件以处理
AnyCPU
,x86
和x64
的3种可能情况。您的目标应在实际构建之前运行,并使用BeforeTargets="BeforeBuild"
。
您可以使用类似的东西
<Content Include="@(WindowsX64IncludeFilesFullPath)"> <Link>$(WindowsX64TargetDir)\$([MSBuild]::MakeRelative($(MSBuildThisFileDirectory)..\build\x64\, %(FullPath)))</Link> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content>
签出:https://github.com/mfkl/libvlc-nuget/blob/master/build/VideoLAN.LibVLC.Windows.targets