c# - 在 Xamarin.Android 使用的 NuGet 包中包含本机库
问题描述
我有一个两部分的项目。第一部分是一组包装原生 .dll 或 .so 库的 C# 绑定。这会生成一个 NugGet 包,然后由其他项目使用。
另一个是使用这些 C# 绑定的 Xamarin Forms 项目。我的 Xamarin 项目的 UWP 部分在 NuGet 包中查找本机库没有问题。但是,Android 项目找不到它。事实上,打开 APK 会发现原生 .so 文件永远不会进入。
我正在使用NuGet 的机制来包含特定于架构的库,方法是将每个特定于平台的 .dll-or-.so 包含在一个/runtimes/platform-arch/native/
文件夹中。对于绑定项目,我的文件夹结构如下所示:
...并且我可以确认文件夹结构已正确保存在生成.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/scannit NuGet 包: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 机器上编译。
您可能需要修改您的目标文件以处理 3 种可能的情况AnyCPU
,x86
并且x64
. 您的目标应该在实际构建之前运行,使用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
推荐阅读
- function - 如何在 Kotlin 中编写(和调用)通用 eval 函数
- node.js - 试图将 tensorflow python 移植到 javascript
- c# - 在 WPF 中实现“关于”菜单项
- sql - 如何在 Impala/hive 中重新格式化多个不同的日期
- javascript - 使用模板文字作为对象
- java - 如何查找 HeapQueue 是否包含 Java 中的值?
- java - 如何将 Object 类型的对象向下转换为数组?
- javascript - HTML / JS / 在选项卡中花费的时间
- node.js - DialogFlow Webhook 适用于 DF 但不适用于 Google Assistant Simulator
- javascript - Vue/Vuex - 模块二依赖于模块一,模块一从服务器获取数据