如何在C#中跳过可选参数(pioRecvPci)? 我认为主要问题是在C中,参数是一个指针,所以可以提供NULL,而在C#中,使用结构上的ref关键字,根据定义,它不能为空。
C代码
typedef struct {
DWORD dwProtocol;
DWORD cbPciLength;
} SCARD_IO_REQUEST;
LONG WINAPI SCardTransmit(
__in SCARDHANDLE hCard,
__in LPCSCARD_IO_REQUEST pioSendPci,
__in LPCBYTE pbSendBuffer,
__in DWORD cbSendLength,
__inout_opt LPSCARD_IO_REQUEST pioRecvPci,
__out LPBYTE pbRecvBuffer,
__inout LPDWORD pcbRecvLength
);
C#代码
[StructLayout(LayoutKind.Sequential)]
public struct SCARD_IO_REQUEST
{
public int dwProtocol;
public int cbPciLength;
}
[DllImport("winscard.dll")]
public static extern int SCardTransmit(
int hCard,
ref SCARD_IO_REQUEST pioSendRequest,
ref byte SendBuff,
int SendBuffLen,
ref SCARD_IO_REQUEST pioRecvRequest,
ref byte RecvBuff,
ref int RecvBuffLen);
答案 0 :(得分:3)
您可以将struct
更改为class
,然后传递null
。请记住,C#struct
与C ++ struct
完全不同,在这里您真的想要使用C#class
。
或者,如果您始终要忽略pioRecvRequest
,请更改SCardTransmit
的签名,以便pioRecvRequest
的类型为IntPtr
。然后通过IntPtr.Zero
获取值。
实际上,SCARD_IO_REQUEST
只是一个标题,如果你想在调用中传递它,你必须自己管理这个结构和额外的缓冲空间,所以IntPtr
是正确的选择。然后,您必须使用Marshal
函数在调用之前分配和填充结构并解组数据并在调用后释放它。
答案 1 :(得分:3)
C#支持方法重载。你可以在这里利用的东西,重新声明方法,但现在给它一个IntPtr参数类型(没有引用)。并通过IntPtr.Zero。
第二种方法是自己整理结构。声明参数类型IntPtr。并使用Marshal.AllocHGlobal()为结构分配内存,Marshal.StructureToPtr()将结构复制到其中。 Marshal.FreeHGlobal()通话结束后。或者通过IntPtr.Zero。显然,过载技巧不那么痛苦。