Я работаю с SQL VDI и пытаюсь передать структуру с C# на C++ через COM-интерфейс. Структура определена в C++ заголовок как:Выравнивание структуры в C#
#pragma pack(8)
struct VDConfig
{
unsigned long deviceCount;
unsigned long features;
unsigned long prefixZoneSize;
unsigned long alignment;
unsigned long softFileMarkBlockSize;
unsigned long EOMWarningSize;
unsigned long serverTimeOut;
unsigned long blockSize;
unsigned long maxIODepth;
unsigned long maxTransferSize;
unsigned long bufferAreaSize;
} ;
Для имитации этого, я определил структуру в C#, как:
[StructLayout(LayoutKind.Explicit)]
public struct VDConfig
{
[FieldOffset(0)]
public uint deviceCount;
[FieldOffset(4)]
public uint features;
[FieldOffset(8)]
public uint prefixZoneSize;
[FieldOffset(12)]
public uint alignment;
[FieldOffset(16)]
public uint softFileMarkBlockSize;
[FieldOffset(20)]
public uint EOMWarningSize;
[FieldOffset(24)]
public uint serverTimeout;
[FieldOffset(28)]
public uint blockSize;
[FieldOffset(32)]
public uint maxIODepth;
[FieldOffset(36)]
public uint maxTransferSize;
[FieldOffset(40)]
public uint bufferAreaSize;
}
Я также попытался определить структуру, как LayoutKind.Sequential и попробовал его с Pack = 8. Однако я определяю структуру, когда пытаюсь передать ее функции, она терпит неудачу, и я получаю ошибку «Выравнивание должно быть 2 ** n и < = гранулярность распределения системы». Я попытался определение функции, которая принимает структуру, как:
int CreateEx([MarshalAs(UnmanagedType.LPWStr)]string instanceName,
[MarshalAs(UnmanagedType.LPWStr)]string name,
IntPtr config);
и
int CreateEx([MarshalAs(UnmanagedType.LPWStr)]string instanceName,
[MarshalAs(UnmanagedType.LPWStr)]string name,
ref VDConfig config);
я получаем тот же результат с любым определением. Может ли кто-нибудь сказать мне, что я здесь делаю неправильно?
Редактировать: Присмотревшись ближе, я также получаю сообщение об ошибке «Количество устройств должно быть в [1..64]». Я устанавливаю счет устройства в 1 и в соответствии с вышеприведенной ошибкой, почти похоже, что функция не получает мою структуру вообще. Не знаю, помогает ли это, или нет, но, возможно, это что-то вызовет для кого-то.
По запросу здесь представлены интерфейсные структуры. В C++:
MIDL_INTERFACE("d0e6eb07-7a62-11d2-8573-00c04fc21759")
IClientVirtualDeviceSet2 : public IClientVirtualDeviceSet
{
public:
virtual HRESULT STDMETHODCALLTYPE CreateEx(
/* [in] */ LPCWSTR lpInstanceName,
/* [in] */ LPCWSTR lpName,
/* [in] */ struct VDConfig *pCfg) = 0;
virtual HRESULT STDMETHODCALLTYPE OpenInSecondaryEx(
/* [in] */ LPCWSTR lpInstanceName,
/* [in] */ LPCWSTR lpSetName) = 0;
};
И мой C# версии:
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("d0e6eb07-7a62-11d2-8573-00c04fc21759")]
public interface IClientVirtualDeviceSet2
{
void CreateEx([In, MarshalAs(UnmanagedType.LPWStr)]string instanceName,
[In, MarshalAs(UnmanagedType.LPWStr)]string name,
[In]ref VDConfig config);
void OpenInSecondaryEx([MarshalAs(UnmanagedType.LPWStr)]string instanceName,
[MarshalAs(UnmanagedType.LPWStr)]string lpSetName);
}
Вы пробовали последовательно с пакетом (8) вместе без FieldOffset? –
Да. Я получаю тот же результат. –
Вы фокусируетесь на неправильной проблеме. Это просто не нравится значение, указанное для VDConfig.выравнивающий элемент. Вы должны следовать его совету и использовать значение, которое имеет силу 2 и <= 65536. –