Sto cercando di creare alcuni file vhd/vhdx usando l'API VHD in C#.Unione C++ in C# - comportamento strano
C'è un C++ unione che assomiglia a questo:
typedef struct _CREATE_VIRTUAL_DISK_PARAMETERS
{
CREATE_VIRTUAL_DISK_VERSION Version;
union
{
struct
{
GUID UniqueId;
ULONGLONG MaximumSize;
ULONG BlockSizeInBytes;
ULONG SectorSizeInBytes;
PCWSTR ParentPath;
PCWSTR SourcePath;
} Version1;
struct
{
GUID UniqueId;
ULONGLONG MaximumSize;
ULONG BlockSizeInBytes;
ULONG SectorSizeInBytes;
ULONG PhysicalSectorSizeInBytes;
PCWSTR ParentPath;
PCWSTR SourcePath;
OPEN_VIRTUAL_DISK_FLAG OpenFlags;
VIRTUAL_STORAGE_TYPE ParentVirtualStorageType;
VIRTUAL_STORAGE_TYPE SourceVirtualStorageType;
GUID ResiliencyGuid;
} Version2;
struct
{
GUID UniqueId;
ULONGLONG MaximumSize;
ULONG BlockSizeInBytes;
ULONG SectorSizeInBytes;
ULONG PhysicalSectorSizeInBytes;
PCWSTR ParentPath;
PCWSTR SourcePath;
OPEN_VIRTUAL_DISK_FLAG OpenFlags;
VIRTUAL_STORAGE_TYPE ParentVirtualStorageType;
VIRTUAL_STORAGE_TYPE SourceVirtualStorageType;
GUID ResiliencyGuid;
PCWSTR SourceLimitPath;
VIRTUAL_STORAGE_TYPE BackingStorageType;
} Version3;
};
} CREATE_VIRTUAL_DISK_PARAMETERS, *PCREATE_VIRTUAL_DISK_PARAMETERS;
Sto cercando di convertire in C#, ma non avendo molta fortuna. Non mi interessa affatto Version3, quindi lo lascio fuori.
Ho provato un certo numero di cose e il meglio che potevo ottenere era che la versione2 funzionasse (facendo qualcosa di veramente bizzarro), ma non sono mai riuscito a far funzionare la versione 1 e la versione 2 allo stesso tempo.
La soluzione che ha esercitato i migliori risultati finora è stato questo, ma ci deve essere qualcosa di sbagliato lì perché Version1 semplicemente non funziona, e SectorSizeInBytes
in Version1 è un ulong
piuttosto che uint
(se cambio a uint
come dovrebbe essere, mi rompere Version2 e Version1 ancora non funziona!)
[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
public struct CreateVirtualDiskParameters
{
[FieldOffset(0)] public CreateVirtualDiskParametersVersion1 Version1;
[FieldOffset(0)] public CreateVirtualDiskParametersVersion2 Version2;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct CreateVirtualDiskParametersVersion1
{
public CreateVirtualDiskVersion Version;
public Guid UniqueId;
public ulong MaximumSize;
public uint BlockSizeInBytes;
public ulong SectorSizeInBytes;
public string ParentPath;
public string SourcePath;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct CreateVirtualDiskParametersVersion2
{
public CreateVirtualDiskVersion Version;
public Guid UniqueId;
public ulong MaximumSize;
public uint BlockSizeInBytes;
public uint SectorSizeInBytes;
public uint PhysicalSectorSizeInBytes;
public string ParentPath;
public string SourcePath;
public OpenVirtualDiskFlags OpenFlags;
public VirtualStorageType ParentVirtualStorageType;
public VirtualStorageType SourceVirtualStorageType;
public Guid ResiliencyGuid;
}
so teoricamente il campo Version
deve essere impostato al di fuori dei struct versione e ho provato anche quello, ma appena si rompe cose ancora più divertenti ...
Quindi qualcuno può consigliare come tradurre correttamente quanto sopra in C#, lasciando fuori la struttura Version3 in quanto non è necessaria?
'ULONGLONG (64 bit)' e 'ULONG (32 bit)' entrambi sembrano essere mappati a 'ulong (64 bit)'. – AlexD
Hai provato a stampare gli scostamenti dei membri delle tue strutture C++? –
@TheodorosChatzigiannakis non è sicuro di come lo farei tenendo presente che contiene enum/structs e stringhe. Voglio dire, che taglia sarebbero? Sono aperto a provarlo, fammi sapere quali valori usare e ti darò una possibilità. – cogumel0