1

C# でオプションのパラメーター (pioRecvPci) をスキップするにはどうすればよいですか? 主な問題は、C ではパラメーターがポインターであるため、NULL を指定できることですが、C# では構造体の ref キーワードが使用されますが、これは定義により null にすることはできません。

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);
4

2 に答える 2

3

C# はメソッドのオーバーロードをサポートしています。ここで利用できるものとして、メソッドを再宣言しますが、IntPtr 引数の型 (ref なし) を指定します。IntPtr.Zero を渡します。

2 番目の方法は、構造を自分でマーシャリングすることです。引数の型 IntPtr を宣言します。Marshal.AllocHGlobal() を使用して構造体にメモリを割り当て、Marshal.StructureToPtr() を使用して構造体をコピーします。呼び出し後の Marshal.FreeHGlobal() 。または IntPtr.Zero を渡します。明らかに、オーバーロード トリックの方がはるかに苦痛が少ないです。

于 2012-08-10T13:14:18.000 に答える
3

structを aに変更してからclassを渡すことができますnull。C#structは C++ とはまったく異なるstructことに注意してください。ここでは、本当に C# を使用したいと考えていますclass

または、常に無視したい場合は、タイプが であるようpioRecvRequestに の署名を変更します。次に、値を渡します。SCardTransmitpioRecvRequestIntPtrIntPtr.Zero

実際には、これSCARD_IO_REQUESTは単なるヘッダーであり、呼び出しでそれを渡したい場合は、この構造と追加のバッファー スペースを自分で管理する必要があるためIntPtr、正しい選択です。次に、Marshal関数を使用して、呼び出しの前に構造体を割り当てて埋め、データを非整列化し、呼び出し後に解放する必要があります。

于 2012-08-10T12:21:19.147 に答える