Windows 和 Linux for .NET Core 之间的封送处理有什么区别?



我正在尝试将现有库迁移到.NET Core,以便能够在Linux下运行它。

在 Linux 中使用库时,运行时会抛出 System.ArgumentException:

ConsoleApp6

中发生了类型为"System.ArgumentException"的未处理异常.dll:"类型'ConsoleApp6.MyStruct'不能封送为非托管结构;无法计算有意义的大小或偏移量。

堆栈跟踪: at System.Runtime.InteropServices.Marshal.OffsetOfHelper(IRuntimeFieldInfo f( at ConsoleApp6.Program.Main(String[] args( in C:\Users\user\source\repos\ConsoleApp6\ConsoleApp6\Program.cs:line 10

在Windows中,它按预期工作。 下面是演示该问题的简单控制台应用:

using System;
using System.Runtime.InteropServices;
namespace ConsoleApp6
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine((Int32) Marshal.OffsetOf<MyStruct>("buffer"));
Console.ReadLine();
}
}
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)]
public struct MyStruct
{
public Int16 number;
public byte[] buffer;
}
}

这是 csproj 文件:

<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.2</TargetFramework>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.7.12" />
</ItemGroup>
</Project>

我希望输出在Windows和Linux中4,但在Linux中它会抛出上述异常。

在 .NET Core 中,您不能使用OffsetOf<T>,根据文档:

OffsetOf(Type, String)
返回托管类的非托管形式的字段偏移量。

OffsetOf<T>(String)[在 .NET Framework 4.5.1 及更高版本中受支持]

返回指定托管类的非托管形式的字段偏移量。

为了使您的代码在 Linux 上运行,您需要改用OffsetOf(Type, String)重载。

Console.WriteLine((Int32) Marshal.OffsetOf(typeof(MyStruct),"buffer"));

我已经深入研究了CLR源代码;没有明显的理由说明为什么你的代码不应该在Linux上运行。我可以看到,它Marshalable的定义特征是它是否是一个接口。

我将深入挖掘 -- 我在vm文件夹中看到源代码;但我也希望看到每个目标环境的源代码,但我没有看到。

最新更新