Собственная зависимость DllImport из пакета NuGet не работает на net472, но работает на netcoreapp2.2 - PullRequest
4 голосов
/ 14 апреля 2019

Мой проект в настоящее время работает безупречно на .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 со следующимoutput.

├── [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)'

Я попытался добавить явную цель к net472 в моем пакете NuGet, не сработало.

Я не получаю никаких ошибок, когдацели моего потребляющего проекта netcoreapp2.2.

Как сделать так, чтобы моя нативная зависимость была обнаружена с помощью свойства DllImport при нацеливании net472?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...