Я пытаюсь вызвать функцию в C
, которая имеет следующую подпись от C#
typedef struct _wfs_result
{
ULONG RequestID;
USHORT hService;
TIMESTAMP tsTimestamp;
LONG hResult;
union {
DWORD dwCommandCode;
DWORD dwEventID;
} u;
LPVOID lpBuffer;
} WFSRESULT, *LPWFSRESULT;
LONG WFSGetInfo(USHORT hService, DWORD dwCategory, LPVOID lpQueryDetails, DWORD dwTimeOut, LPWFSRESULT *lppResult)
typedef struct _wfs_pin_status
{
WORD fwDevice;
WORD fwEncStat;
LPSTR lpszExtra;
DWORD dwGuidLights[WFS_PIN_GUIDLIGHTS_SIZE];
WORD fwAutoBeepMode;
DWORD dwCertificateState;
WORD wDevicePosition;
USHORT usPowerSaveRecoveryTime;
} WFSPINSTATUS, *LPWFSPINSTATUS;
и мой код C#
выглядит следующим образом:
[DllImport("msxfs")]
public static extern int WFSGetInfo(ushort hService, uint dwCategory, IntPtr lpQueryDetails, uint dwTimeOut, ref WFSRESULT lppResult);
[StructLayout(LayoutKind.Explicit)]
public struct WFSRESULT
{
[FieldOffset(0)]
public uint RequestID;
[FieldOffset(4)]
public ushort hService;
[FieldOffset(6)]
public SYSTEMTIME tsTimestamp;
[FieldOffset(22)]
public int hResult;
[FieldOffset(26)]
public uint dwCommandCode;
[FieldOffset(26)]
public uint dwEventID;
[FieldOffset(30)]
public IntPtr lpBuffer; //It should be pointer to a structure that contain more information
}
[StructLayout(LayoutKind.Sequential)]
public struct SYSTEMTIME
{
public ushort wYear;
public ushort wMonth;
public ushort wDayOfWeek;
public ushort wDay;
public ushort wHour;
public ushort wMinute;
public ushort wSecond;
public ushort wMilliseconds;
}
[StructLayout(LayoutKind.Sequential)]
public struct WFSPINSTATUS
{
public ushort fwDevice;
public ushort fwEncStat;
public string lpszExtra;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public uint[] dwGuidLights;
public ushort fwAutoBeepMode;
public uint dwCertificateState;
public ushort wDevicePosition;
public ushort usPowerSaveRecoveryTime;
}
private void WfsGetInfo()
{
WFSRESULT wfsRESULT = new WFSRESULT();
int hResult = WFSGetInfo(_lphService, InfoCommands.WFS_INF_PIN_CAPABILITIES, IntPtr.Zero, WFS_INDEFINITE_WAIT, ref wfsRESULT);
WFSPINSTATUS pinStatus = Marshal.PtrToStructure<WFSPINSTATUS>(wfsRESULT.lpBuffer);
}
Моя проблема в том, что всякий раз, когда я вызываю функцию WFSGetInfo
, она будет выполнена успешно (hResult == 0
), но будут заполнены только RequestID
в wfsRESULT
, а все остальные значения будут равны 0 (значение по умолчанию), и при попытке преобразовать lpBuffer
в WFSPINSTATUS
следующее исключение произошло. System.NullReferenceException: 'Object reference not set to an instance of an object.'
Не думаю, что проблема в вызываемой dll msxfs
, потому что это стандартная windows dll.
Я пробую много решений и техник (например, Я пытаюсь установить SYSTEMTIME
layout на Explicit
), но с тем же результатом; Я не буду добавлять свои испытания, чтобы сократить код.
Я провел большой поиск относительно структуры маршалинга и объединения в C
, и следующий сайт был очень полезен Маршалинг с C#
Я не уверен, что эта информация полезна, но я строю интеграцию CEN/XFS
с устройством EPP.