NuGet包中的DllImport本机依赖性在net472上不起作用,但在netcoreapp2.2上有效

问题描述 投票:5回答:1

我的项目目前在.NET Core(Linux / OSX / Windows / netcoreapp2.2)上可以正常运行。它[[应该也可以在net472上工作,但是由于某些原因,DllImport找不到本机依赖性。

可以找到一个简单的副本here,但我将在后一问题中进一步扩展此问题。

这里是包含本地依赖项的打包项目。

<Project Sdk="Microsoft.NET.Sdk"> <Import Project="../../build/common.props" /> <PropertyGroup> <TargetFramework>netstandard2.0</TargetFramework> <RuntimeIdentifier>win-x64</RuntimeIdentifier> <DisableImplicitFrameworkReferences>true</DisableImplicitFrameworkReferences> <EnableDefaultItems>false</EnableDefaultItems> <GenerateAssemblyInfo>false</GenerateAssemblyInfo> <IncludeBuildOutput>false</IncludeBuildOutput> </PropertyGroup> <ItemGroup> <ProjectReference Include="..\net\Qml.Net\Qml.Net.csproj" /> </ItemGroup> <ItemGroup> <Content Include="output/**/*"> <PackagePath>runtimes/win-x64/native/</PackagePath> <Pack>true</Pack> </Content> </ItemGroup> </Project>

这将产生一个带有以下输出的NuGet包。

├── [Content_Types].xml ├── package │   └── services │   └── metadata │   └── core-properties │   └── e803485f4a674e8d9d0155224fa9cbc2.psmdcp ├── Qml.Net.WindowsBinaries.nuspec ├── _rels └── runtimes └── win-x64 └── native └── QmlNet.dll 8 directories, 4 files

这是我正在消耗的项目。

<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net472</TargetFramework> <RunWorkingDirectory>$(MSBuildProjectDirectory)</RunWorkingDirectory> </PropertyGroup> <ItemGroup> <None Remove="**\*.qmlc" /> </ItemGroup> <ItemGroup> <PackageReference Include="Qml.Net" Version="0.9.0-alpha.5" /> <PackageReference Include="Qml.Net.WindowsBinaries" Version="0.9.0-alpha.5" /> </ItemGroup> <ItemGroup> <Content Include="images\**" CopyToPublishDirectory="Always" /> <Content Include="pages\**" CopyToPublishDirectory="Always" /> <Content Include="Main.qml" CopyToPublishDirectory="Always" /> </ItemGroup> </Project>

这是尝试执行PInvoke的简单代码。

using System; using System.Runtime.InteropServices; using Qml.Net.Runtimes; namespace Features { class Program { // NOTE: This works if I provide absolute path to QmlNet.dll [DllImport("QmlNet")] internal static extern long qml_net_getVersion(); static int Main(string[] args) { // This is need to prep Qt runtime that QmlNet.dll depends on. // It is required, but it is irrelvant to the issue we are experiencing. RuntimeManager.DiscoverOrDownloadSuitableQtRuntime(); // The following works on netcoreapp2.2, but not on 4.7.2. Console.WriteLine(qml_net_getVersion()); return 0; } } }

当我运行它时,我得到:

System.DllNotFoundException: 'Unable to load DLL 'QmlNet': The specified module could not be found. (Exception from HRESULT: 0x8007007E)'

我尝试在NuGet程序包中向net472添加显式目标,但是没有用。

我使用的项目目标为netcoreapp2.2时没有任何错误。

[以DllImport为目标时,如何使我的本机依赖性成为通过net472发现的属性?

.net nuget pinvoke
1个回答
0
投票
This answer帮助我从nuget包中加载了本机文件。我唯一要做的就是使用当前目录,例如[]

private static IntPtr ImportResolver(string libraryName, Assembly assembly, DllImportSearchPath? searchPath) { IntPtr libHandle = IntPtr.Zero; //TODO: Add check for windows if needed. if (libraryName == WrapperFFI && RuntimeInformation.IsOSPlatform(OSPlatform.Linux) && Environment.Is64BitOperatingSystem) { var res = NativeLibrary.TryLoad(System.IO.Directory.GetCurrentDirectory()+"/bin/Debug/netcoreapp3.1/runtimes/linux-x64/native/libwrapper_ffi.so", out libHandle); if (!res) { res = NativeLibrary.TryLoad(System.IO.Directory.GetCurrentDirectory()+"/bin/Release/netcoreapp3.1/runtimes/linux-x64/native/libwrapper_ffi.so", out libHandle); } } return libHandle; }

编辑:

尽管以上修复程序大多数都可以使用,但是当我拉出基于私人仓库的nuget程序包时,它无效。私有仓库的本机库是在centos上构建的,这会导致二进制文件更小,但是我仍然无法在ubuntu开发机上加载异常。 centos库比lubuntu库具有更多的ldd显示的依赖项]

Ubuntu:

enter image description here

Centos:

enter image description here

所以我将创建一个ubuntu build boks来快速解决该问题

© www.soinside.com 2019 - 2024. All rights reserved.