2

我正在尝试调用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),但只会填充RequestIDin wfsRESULT并且所有其他值都将为 0(默认值),并且当我尝试转换lpBufferWFSPINSTATUS以下异常时发生。 System.NullReferenceException: 'Object reference not set to an instance of an object.'

我不认为问题出在调用的 dll 中,msxfs因为它是标准的 windows dll。

我尝试了很多解决方案和技术(例如,我尝试将SYSTEMTIME布局设置为Explicit)但结果相同;我不会添加我的试验来缩短代码。

我做了很多关于编组结构和联合的搜索,以下站点对使用 C#C进行编组非常有帮助

我不确定这些信息是否有用,但我正在构建CEN/XFS与 EPP 设备的集成。

4

0 回答 0