【发布时间】:2016-06-04 00:03:57
【问题描述】:
我正在尝试使用 C# 中的 VHD API 创建一些 vhd/vhdx 文件。
有一个 C++ 联合,如下所示:
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;
我正在尝试将其转换为 C#,但运气不佳。我对第 3 版根本不感兴趣,所以我把它排除在外。
我已经尝试了很多事情,我能做到的最好的事情就是让 Version2 工作(通过做一些非常奇怪的事情),但我从来没有设法让 Version1 和 Version2 同时工作。
到目前为止,效果最好的解决方案就是这个,但肯定有问题,因为 Version1 根本不起作用,而且 Version1 中的 SectorSizeInBytes 是 ulong 而不是 uint (如果我将其更改为 uint 应该是这样,我会破坏 Version2 并且 Version1 仍然无法正常工作!)
[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;
}
我知道理论上 Version 字段应该设置在 Version 结构之外,我也尝试过,但它只会让事情变得更有趣......
那么,有人可以建议如何将上面的内容正确地翻译成 C#,而省去不需要的 Version3 结构吗?
【问题讨论】:
-
ULONGLONG (64 bit)和ULONG (32 bit)似乎都映射到ulong (64 bit)。 -
您是否尝试过打印出 C++ 结构成员的偏移量?
-
@TheodorosChatzigiannakis 不太清楚我会怎么做,因为它包含枚举/结构和字符串。我的意思是,它们会有多大?我愿意尝试,请告诉我要使用的值,我会试一试。
-
@cogumel0 我的意思是使用
offsetof宏。让它为您打印偏移量并在 C# 端明确定义这些偏移量。 -
一个问题是
ParentPath和SourcePath是本机结构中的原始指针,但C# 代码中的string类中包含不止一个指针。跨度>