Sto cercando di capire perché il secondo esempio di seguito funziona senza problemi, ma il primo esempio mi dà l'eccezione qui sotto. Mi sembra che entrambi gli esempi dovrebbero dare un'eccezione basata sulla descrizione. Qualcuno può illuminarmi?C# StructLayout.Explicit Domanda
eccezione non gestita: System.TypeLoadException: Impossibile tipo di carico 'StructTest.OuterType' da assembly 'StructTest, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null' perché contiene oggetto campo a offset 0 che è allineato in modo errato o sovrapposto da un campo non oggetto.
presso StructTest.Program.Main (String [] args) Premere un tasto qualsiasi per continuare. . .
Esempio 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);
}
}
}
Esempio 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);
}
}
}
Vedo, quindi, se volessi farlo correttamente in modo che funzionasse correttamente su macchine a 32 o 64 bit, avrei bisogno di usare un offset rispettivamente di 8 e 0, corretto? Il problema è che quello che volevo veramente creare era un sindacato e sembra che questo finirà per non essere uno se non posso usare lo stesso offset. –
Sì. Funzionerà su CLR x64 con offset 8 e 0. Si noti che mentre lo snippet di codice funziona, se lo si fa in un'app per il mondo reale, si sta probabilmente interagendo con alcune cose non gestite, che si aspettano gli offset esatti. Se lo imposti su 8, potrebbe non funzionare su macchine a 32 bit (non questo frammento stesso, ma il codice non gestito con cui stai interagendo). –
A proposito, ** puoi ** avere campi sovrapposti se sono di * tipi non gestiti *, ma un array .NET è un tipo di riferimento (che non può essere considerato un tipo non gestito per specifica C#). Quindi non puoi avere un tipo di riferimento come membro di un sindacato in C#. Se hai davvero bisogno di questo, dovresti prendere in considerazione l'uso di cose come i tipi di puntatore come membri struct invece di un array. –