UnmanagedExports、DllExport 和 NativeAOT 在 .NET6.0 中被破坏

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

我有一个以前用 .NET Framework 编写的应用程序。 Robert Giesecke UnmanagedExport 非常适合将

[DllExport]
属性添加到我的函数中,以将它们公开给本机语言。

现在我们已经升级到.Net6.0了,这似乎不起作用了。这些函数可导出并使用

dumpbin
可见。它们确实以本地语言加载,并且可以找到函数地址。虽然,在执行该函数时,我遇到了异常
Unhandled exception at 0x00007FFB928CCD29 (KernelBase.dll) in NativeExportTest.exe: 0xE0434352 

如果我切换回 .NET Framework 或 .NET Standard,一切都会恢复正常。我已经尝试过以下软件包;

  • 非托管导出.重新打包
  • 非托管导出.重新打包.升级
  • Dll 导出
  • NativeAOT(可以工作,但不支持 .NET 6.0 中使用的所有功能)。

我还查看了 .NET6.0 的

[UnmanagedCallersOnlyAttribute]
,但底层的本机语言很奇怪,在运行时被编译成 C++。我不相信它支持回调。

有没有办法将 .NET6.0 c# 函数导出到本地语言而不依赖回调?

我只需要 Windows 的解决方案。

C#

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net6.0-windows</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
    <Platforms>AnyCPU;x64</Platforms>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="UnmanagedExports.Repack.Upgrade" Version="1.2.1" />
  </ItemGroup>
</Project>

public class Class1
{
    [DllExport]
    public static int _add(int a, int b)
    {
        return a + b;
    }
}

一些 C++ 适用于 .NET Framework,但不适用于 .NET Core。

const TCHAR* pemodule = _T("path to release dll");
HMODULE lib = LoadLibrary(pemodule);
typedef int( *_add)(int a, int b);
auto pAdd = (_add)GetProcAddress(lib, "_add");
int c = pAdd(1,2); // Exception here

按照 Hans Passants 启用混合调试的建议,我遇到了一个新的异常。现在,在加载任何代码之前,异常会显示在控制台中:

Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'System.Runtime, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified.

c# c++ .net-core .net-6.0
1个回答
1
投票

我通过升级到 .NET 7.0 并使用内置导出功能

[UnmanagedCallersOnly]
而不是
[DllExport]
来实现此功能。可以从 C++ 调用函数并按预期显示在 dumpbin 中。

请注意,项目必须发布为

PublishAot
Shared
SelfContained

dotnet publish -f net7.0 -c Release -r win-x64 -p:PublishAot=true -p:NativeLib=Shared -p:SelfContained=true 

不幸的是,这看起来仍然只是 x64 的解决方案。我正在连接到在 x64 Windows 上作为 x86 运行的旧应用程序。为此,我创建了 .NET Framework x86

DllExport
,它使用 API 调用充当 .NET Core 的层。希望未来能有更好的 NativeAOT 支持。

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