1

C#で相互運用機能を使用してSCardGetCardTypeProviderNameを使用しようとしています。パラメータの1つは参照です。これは、渡されたカードコンテキストに従って、スマートカードのプロバイダーの名前を返すことになっています。これは、私が使用しているコードです。

IntPtr hSC = { value comes from call using SCardEstablishContext }
string cardName = { value comes from SCardUIDlgSelectCard }
int providerNameLength = 256;
string providerName = string.Empty;  //doesn't matter how I initialize this

[DllImport("winscard.dll", CharSet = CharSet.Ansi, SetLastError = true)]
public static extern Int32 SCardGetCardTypeProviderName(IntPtr hContext, string szCardName, uint dwProviderId, ref string szProvider, ref int pcchProvider);

int lReturn = SCardGetCardTypeProviderName(hSC, cardName, SCARD_PROVIDER_CSP, ref providerName, ref providerNameLength);

ただし、providerNameは常に空に戻りますが、providerNameLengthは43に変更されるため、マーシャリングの問題だと思います。しかし、私はproviderNameを次のようにマーシャリングしようとしました:

  • LPWStr
  • LPTStr
  • LPStr

後者の2つの場合、空の文字列の代わりに、奇妙な文字列が表示されます。これも、マーシャリング/翻訳の問題だと思います。

4

1 に答える 1

3

文字列パラメータをStringBuilderとして宣言します。

[DllImport("winscard.dll"]
public static extern int SCardGetCardTypeProviderName(
    IntPtr hContext,
    string szCardName, 
    uint dwProviderId, 
    StringBuilder szProvider, 
    ref int pcchProvider
);
....
StringBuilder providerName = new StringBuilder(providerNameLength);
int lReturn = SCardGetCardTypeProviderName(
    hSC, 
    cardName, 
    SCARD_PROVIDER_CSP, 
    providerName, 
    ref providerNameLength
);

CharSetのデフォルト値を繰り返す必要はなく、これらのAPI関数はWin32の最後のエラーメカニズムを使用しません。

于 2013-02-07T07:48:35.010 に答える