我无法修复由winscard.dll 库包装器中的SCardConnect函数导致的内存泄漏。有没有办法通过winscard.dll修复内存
总结:当SCardConnect成功返回 0 时,这意味着读卡器上有一张卡,内存就会爆炸。
细节:
我发现SCardEstablishContext也会造成内存泄漏,所以我尽量减少对该函数的使用。我也尝试使用SCardStatusChange函数,但它也会造成内存泄漏并且逻辑很复杂。
- 包装卡.cs:
[DllImport("winscard.dll")]
public static extern int SCardConnect(int hContext, string szReaderName, int dwShareMode, int dwPrefProtocol, ref int phCard, ref int ActiveProtocol);
- 主要代码:(省略了一些全局变量)
public Form1()
{
InitializeComponent();
do
{
if (this.Connect())
{
}
else
{
}
}
while (true);
}
public bool Connect()
{
if(string.IsNullOrEmpty(readername))
try
{
readername = this.GetReadersList()[0];
}
catch(Exception e) { }
retCode = Card.SCardConnect(hContext, readername, Card.SCARD_SHARE_SHARED,
Card.SCARD_PROTOCOL_T0 | Card.SCARD_PROTOCOL_T1, ref hCard, ref Protocol);
if (retCode != Card.SCARD_S_SUCCESS)
{
return false;
}
else
{
return true;
}
}
public List<string> GetReadersList()
{
string ReaderList = "" + Convert.ToChar(0);
int indx;
int pcchReaders = 0;
string rName = "";
List<string> lstReaders = new List<string>();
//Establish Context
retCode = Card.SCardEstablishContext(Card.SCARD_SCOPE_USER, 0, 0, ref hContext);
// 2. List PC/SC card readers installed in the system
retCode = Card.SCardListReaders(this.hContext, null, null, ref pcchReaders);
if (retCode != Card.SCARD_S_SUCCESS)
{
throw new Exception("Error SCardListReaders");
}
byte[] ReadersList = new byte[pcchReaders];
// Fill reader list
retCode = Card.SCardListReaders(this.hContext, null, ReadersList, ref pcchReaders);
if (retCode != Card.SCARD_S_SUCCESS)
{
throw new Exception("Error SCardListReaders");
}
rName = "";
indx = 0;
while (ReadersList[indx] != 0)
{
while (ReadersList[indx] != 0)
{
rName += (char)ReadersList[indx];
indx++;
}
lstReaders.Add(rName);
rName = "";
indx++;
}
return lstReaders;
}
- 内存诊断: 在此处输入图像描述。
所有内存上升都在读卡器上持卡时。
PS:我在 Window Form、Console 和 Window Service 平台上都试过这个。