[英]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.