我的项目目前在.NET Core(Linux / OSX / Windows / netcoreapp2.2
)上可以正常运行。它[[应该也可以在net472
上工作,但是由于某些原因,DllImport
找不到本机依赖性。
这里是包含本地依赖项的打包项目。
<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
发现的属性?
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:
Centos:
所以我将创建一个ubuntu build boks来快速解决该问题