Warum funktioniert LayoutKind.Sequential anders, wenn eine Struktur ein DateTime-Feld enthält?Warum funktioniert LayoutKind.Sequential anders, wenn eine Struktur ein DateTime-Feld enthält?
Betrachten Sie die folgenden Code (eine Konsolenanwendung, die mit „unsicher“ aktiviert kompiliert werden müssen):
using System;
using System.Runtime.InteropServices;
namespace ConsoleApplication3
{
static class Program
{
static void Main()
{
Inner test = new Inner();
unsafe
{
Console.WriteLine("Address of struct = " + ((int)&test).ToString("X"));
Console.WriteLine("Address of First = " + ((int)&test.First).ToString("X"));
Console.WriteLine("Address of NotFirst = " + ((int)&test.NotFirst).ToString("X"));
}
}
}
[StructLayout(LayoutKind.Sequential)]
public struct Inner
{
public byte First;
public double NotFirst;
public DateTime WTF;
}
}
Nun, wenn ich den Code oben laufen, bekomme ich eine Ausgabe ähnlich den folgenden:
Adresse der Struktur = 40F2CC
Adresse erster = 40F2D4
Adresse NotFirst = 40F2CC
Beachten Sie, dass die Adresse zunächst nicht die gleiche wie die a Adresse der Struktur; Die Adresse von NotFirst ist jedoch das gleiche wie die Adresse der Struktur.
Kommentieren Sie jetzt das Feld "DateTime WTF" in der Struktur und führen Sie es erneut aus. Diesmal bekomme ich eine Ausgabe wie folgt aus:
Adresse von struct = 15F2E0
Adresse erster = 15F2E0
Adresse NotFirst = 15F2E8
Now "First" hat haben die gleiche Adresse wie die Struktur
Ich finde dieses Verhalten überraschend angesichts der Verwendung von LayoutKind.Sequential. Kann jemand eine Erklärung geben? Hat dieses Verhalten irgendwelche Auswirkungen bei Interop mit C/C++ - Strukturen, die den COM DATETIME-Typ verwenden?
[EDIT] HINWEIS: Ich habe festgestellt, dass, wenn Sie Marshal.StructureToPtr verwenden(), um die Struktur zu ordnen, werden die Daten ist in der richtigen Reihenfolge vermarshallten, mit dem „First“ Feld zuerst zu sein. Dies scheint darauf hinzudeuten, dass es mit der Interop funktionieren wird. Das Geheimnis ist, warum sich das interne Layout ändert - aber natürlich wird das interne Layout nie spezifiziert, so dass der Compiler tun kann, was er will.
[EDIT2] "unsafe" von der Strukturdeklaration entfernt (es war übrig von einigen Tests, die ich tat).
[EDIT3] Die ursprüngliche Quelle für diese Frage war von den MSDN C# Foren:
Ich denke, Sie haben Ihre eigene Frage beantwortet;) – Doggett
Nun, Gott sei Dank man nie DateTime verwenden, wenn unsicher gehen. :) – leppie
+1 für die Beantwortung Ihrer Frage.Sie sollten eine Antwort mit Ihrer eigenen Antwort erstellen und sie akzeptieren, wenn Sie können. – jgauffin