У меня есть следующие структуры в C ++: (с использованием пакета Pragma 1)
typedef struct _wfs_cdm_physicalcu
{
LPSTR lpPhysicalPositionName;
CHAR cUnitID[5];
ULONG ulInitialCount;
ULONG ulCount;
ULONG ulRejectCount;
ULONG ulMaximum;
USHORT usPStatus;
BOOL bHardwareSensor;
} WFSCDMPHCU, * LPWFSCDMPHCU;
typedef struct _wfs_cdm_cashunit
{
USHORT usNumber;
USHORT usType;
LPSTR lpszCashUnitName;
CHAR cUnitID[5];
CHAR cCurrencyID[3];
ULONG ulValues;
ULONG ulInitialCount;
ULONG ulCount;
ULONG ulRejectCount;
ULONG ulMinimum;
ULONG ulMaximum;
BOOL bAppLock;
USHORT usStatus;
USHORT usNumPhysicalCUs;
LPWFSCDMPHCU *lppPhysical;
} WFSCDMCASHUNIT, * LPWFSCDMCASHUNIT;
typedef struct _wfs_cdm_cu_info
{
USHORT usTellerID;
USHORT usCount;
LPWFSCDMCASHUNIT *lppList;
} WFSCDMCUINFO, * LPWFSCDMCUINFO;
P / Invoke Interop Assistant дает мне следующий вывод:
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, CharSet=System.Runtime.InteropServices.CharSet.Ansi, Pack = 1)]
public struct WFSCDMPHCU {
/// LPSTR->CHAR*
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)]
public string lpPhysicalPositionName;
/// CHAR[5]
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst=5)]
public string cUnitID;
/// ULONG->unsigned int
public uint ulInitialCount;
/// ULONG->unsigned int
public uint ulCount;
/// ULONG->unsigned int
public uint ulRejectCount;
/// ULONG->unsigned int
public uint ulMaximum;
/// USHORT->unsigned short
public ushort usPStatus;
/// BOOL->int
public int bHardwareSensor;
}
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, CharSet=System.Runtime.InteropServices.CharSet.Ansi, Pack = 1)]
public struct WFSCDMCASHUNIT {
/// USHORT->unsigned short
public ushort usNumber;
/// USHORT->unsigned short
public ushort usType;
/// LPSTR->CHAR*
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.LPStr)]
public string lpszCashUnitName;
/// CHAR[5]
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst=5)]
public string cUnitID;
/// CHAR[3]
[System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst=3)]
public string cCurrencyID;
/// ULONG->unsigned int
public uint ulValues;
/// ULONG->unsigned int
public uint ulInitialCount;
/// ULONG->unsigned int
public uint ulCount;
/// ULONG->unsigned int
public uint ulRejectCount;
/// ULONG->unsigned int
public uint ulMinimum;
/// ULONG->unsigned int
public uint ulMaximum;
/// BOOL->int
public int bAppLock;
/// USHORT->unsigned short
public ushort usStatus;
/// USHORT->unsigned short
public ushort usNumPhysicalCUs;
/// LPWFSCDMPHCU*
public System.IntPtr lppPhysical;
}
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential, Pack = 1)]
public struct WFSCDMCUINFO {
/// USHORT->unsigned short
public ushort usTellerID;
/// USHORT->unsigned short
public ushort usCount;
/// LPWFSCDMCASHUNIT*
public System.IntPtr lppList;
}
Однако при использовании Marshal.PtrToStruct (скажем, на WFSCDMCUINFO.lppList) я получаю мусор; при просмотре памяти с помощью Visual Studio фактическое содержимое отображается в другой записи памяти (не в lppList как таковом).
Верны ли эти преобразования? Мое доверие к P / Invoke Interop Assistant неуместно?
EDIT:
Это код, который я использую для маршала в / из IntPtr. Я знаю, что идея Thread - отстой, но я вернусь к этому позже ...
public static IntPtr GetIntPtr(this object obj) {
try {
var handle = GCHandle.Alloc(obj, GCHandleType.Pinned);
var thread = new Thread(() => {
Thread.Sleep(20000);
handle.Free();
});
thread.Start();
return handle.AddrOfPinnedObject();
} catch (ArgumentException) {
var ptr = Marshal.AllocHGlobal(Marshal.SizeOf(obj));
Marshal.StructureToPtr(obj, ptr, false);
return ptr;
}
}
public static T FromIntPtr<T>(this IntPtr ptr) {
if (ptr == IntPtr.Zero)
return default(T);
return (T) Marshal.PtrToStructure(ptr, typeof (T));
}