我正在尝试将现有库迁移到.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
文件夹中看到源代码;但我也希望看到每个目标环境的源代码,但我没有看到。