1

我正在尝试通过 C# 中的互操作使用 SCardGetCardTypeProviderName。其中一个参数是引用,它应该根据传入的卡上下文返回智能卡提供者的名称。这是我正在使用的代码:

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

在后两者的情况下,我得到一串奇怪的字符,而不是空字符串,这让我再次认为这是一个编组/翻译问题。

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 回答