繁体   English   中英

将 C 结构编组到 C#

[英]Marshal a C structure into C#

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

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

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

我对C编组结构和联合进行了大量搜索,以下站点对使用 C#编组非常有帮助

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM