I'm trying to call a function in C
that has the following signature from 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;
and my C#
code look like this:
[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);
}
My problem that whenever I call WFSGetInfo
function it will be succeeded (hResult == 0
), but only RequestID
in
wfsRESULT
will be filled and all other values will be 0 (default value), and when I try to convert lpBuffer
to WFSPINSTATUS
following exception occurred.
System.NullReferenceException: 'Object reference not set to an instance of an object.'
I do not think the problem is in the called dll msxfs
because It is a standard windows dll.
I try a lot of solution and techniques (for example I try to set SYSTEMTIME
layout to Explicit
) but with same result; I will not add my trials to shorten the code.
I done a lot of search regarding marshaling structure and union in C
, and following site was very helpful Marshaling with C#
I'm not sure if this information is helpful but I'm building an CEN/XFS
integration with EPP device.