Tôi đang cố gắng hiểu tại sao ví dụ thứ hai bên dưới hoạt động mà không có vấn đề gì, nhưng ví dụ đầu tiên cho tôi ngoại lệ bên dưới. Dường như với tôi rằng cả hai ví dụ nên đưa ra một ngoại lệ dựa trên mô tả. Ai có thể khai sáng cho tôi không?C# StructLayout.Explicit Câu hỏi
Unhandled Exception: System.TypeLoadException: Không thể loại tải 'StructTest.OuterType' từ lắp ráp 'StructTest, Version = 1.0.0.0, Văn hóa = trung tính, PublicKeyToken = null' vì nó có chứa một trường đối tượng tại số bù trừ 0 được căn chỉnh không chính xác hoặc được chồng lấp bởi trường không đối tượng.
tại StructTest.Program.Main (Chuỗi [] args) Nhấn phím bất kỳ để tiếp tục. . .
Ví dụ 1
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
namespace StructTest
{
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct InnerType
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
char[] buffer;
}
[StructLayout(LayoutKind.Explicit)]
struct OuterType
{
[FieldOffset(0)]
int someValue;
[FieldOffset(0)]
InnerType someOtherValue;
}
class Program
{
static void Main(string[] args)
{
OuterType t = new OuterType();
System.Console.WriteLine(t);
}
}
}
Ví dụ 2
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
namespace StructTest
{
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct InnerType
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
char[] buffer;
}
[StructLayout(LayoutKind.Explicit)]
struct OuterType
{
[FieldOffset(4)]
private int someValue;
[FieldOffset(0)]
InnerType someOtherValue;
}
class Program
{
static void Main(string[] args)
{
OuterType t = new OuterType();
System.Console.WriteLine(t);
}
}
}
Tôi hiểu, vì vậy nếu tôi muốn thực hiện điều này một cách chính xác để nó hoạt động chính xác trên máy 32 hoặc 64 bit, tôi cần phải sử dụng bù 8 và 0 tương ứng, đúng không? Vấn đề là những gì tôi thực sự muốn tạo ra là một công đoàn và có vẻ như điều này sẽ kết thúc không phải là một nếu tôi không thể sử dụng cùng một bù đắp. –
Có. Nó sẽ làm việc trên x64 CLR với offset 8 và 0. Lưu ý rằng trong khi đoạn mã hoạt động, nếu bạn đang làm điều này trong một ứng dụng thế giới thực, có thể bạn đang giao tiếp với một số công cụ không được quản lý, điều này có thể sẽ xảy ra sai số chính xác. Nếu bạn đặt nó thành 8, nó có thể thất bại trên các máy 32 bit (không phải đoạn mã này, nhưng mã không được quản lý mà bạn đang giao tiếp). –
Nhân tiện, bạn ** có thể ** có các trường chồng chéo nếu chúng thuộc loại * không được quản lý *, nhưng một mảng .NET là một kiểu tham chiếu (không thể được coi là kiểu không được quản lý cho mỗi thông số C#). Vì vậy, bạn không thể có một loại tham chiếu như là một thành viên của một công đoàn trong C#. Nếu bạn thực sự cần điều này, bạn nên xem xét việc sử dụng những thứ như các loại con trỏ như các thành viên struct thay vì một mảng. –