在用二代身份证读卡器读身份证时,用的是DLL中的函数,可是DLL是非托管的,读完一次卡不能及时释放资源,只是进行了关闭“CloseComm();”,再次进行读取,会出现错误信息:内存被保护或内存被损坏。试图用GC.SuppressFinalize(this),而释放资源,可是还是不行,应该是要实现IDispose(),或是Using语句吧请问怎样处理才可以手动,也就是显示的释放掉资源,网上有资料,可是不会写释放资源的语句。急啊,今天晚上必须要解决问题的呢???DLL声明:
#region 二代证阅读器接口
        /// <summary>
        /// 二代证阅读器接口
        /// </summary>
        /// <returns></returns>
        [DllImport("kernel32", EntryPoint = "GetModuleFileNameA")]
        static extern int GetModuleFileName(int hModule, string lpFileName, int nSize);        //初始化设备(串口:1-16,USB:1001-1016)
        [DllImport("termb.dll")]
        static extern int InitComm(int X);
        //读卡完毕后,关闭设备
        [DllImport("termb.dll")]
        static extern int CloseComm();
        //证卡验证,返回值不需要判断
        [DllImport("termb.dll")]
        static extern int Authenticate();
        //读基本信息,iActive=1;读卡成功后照片信息存放在zp.bmp文件中;读追加地址,iActive=3;
        [DllImport("termb.dll")]
        static extern int Read_Content(int Active);
 //姓名
        [DllImport("termb.dll")]
        static extern int GetPeopleName(StringBuilder lpBuffer, uint strLen);
        //地址
        [DllImport("termb.dll")]
        static extern int GetPeopleAddress(StringBuilder lpBuffer, uint strLen);
        //身份证号码
        [DllImport("termb.dll")]
        static extern int GetPeopleIDCode(StringBuilder lpBuffer, uint strLen);
        //出生日期
        [DllImport("termb.dll")]
        static extern int GetPeopleBirthday(StringBuilder lpBuffer, uint strLen);
        //民族
        [DllImport("termb.dll")]
        static extern int GetPeopleNation(StringBuilder lpBuffer, uint strLen);
        //性别
        [DllImport("termb.dll")]
        static extern int GetPeopleSex(StringBuilder lpBuffer, uint strLen);
        //发证机关
        [DllImport("termb.dll")]
        static extern int GetDepartment(StringBuilder lpBuffer, uint strLen);
        //证件开始日期
        [DllImport("termb.dll")]
        static extern int GetStartDate(StringBuilder lpBuffer, uint strLen);
        //证件结束日期
        [DllImport("termb.dll")]
        static extern int GetEndDate(StringBuilder lpBuffer, uint strLen);
        //照片
        [DllImport("termb.dll")]
        static extern int GetPhotoBMP(StringBuilder lpBuffer, uint strLen);
        //追加地址
        [DllImport("termb.dll")]
        static extern int GetAppAddress(StringBuilder lpBuffer, uint strLen);
        #endregion        private static int intPort = 0; //端口号
        private static int iRet = 0;
读卡过程:
try
            {
                string str = "";
                str = str.PadLeft(100);
                StringBuilder str1 = new StringBuilder(str);                if (intPort == 0)
                {
                    for (int i = 1; i < 16; i++)
                    {
                        iRet = InitComm(i);
                        if (iRet == 1)
                        {
                            intPort = i;
                            break;
                        }
                    }
                }
                else
                {
                    iRet = InitComm(intPort);
                }                if (intPort == 0)
                {
                    for (int j = 1001; j < 1016; j++)
                    {
                        iRet = InitComm(j);
                        if (iRet == 1)
                        {
                            intPort = j;
                            break;
                        }
                    }
                }                              iRet = Authenticate();
                iRet = Read_Content(1);
                iRet = GetPeopleName(str1, 100);
                tbName_Identity.Text = str1.ToString().Trim();                str1.Length = 0;
                str1.Append(str);
                iRet = GetPeopleAddress(str1, 100);
                tbAddress_Identity.Text = str1.ToString().Trim();                str1.Length = 0;
                str1.Append(str);
                iRet = GetPeopleIDCode(str1, 100);
                tbNum_Identity.Text = str1.ToString().Trim();                str1.Length = 0;
                str1.Append(str);
                iRet = GetPeopleBirthday(str1, 100);
                string brithdayStr = str1.ToString().Trim();
                string strtime1 = brithdayStr.Insert(4, "-").ToString();
                string strtime2 = strtime1.Insert(7, "-").ToString();                tbTime_Identity.Text = strtime2;                str1.Length = 0;
                str1.Append(str);
                iRet = GetPeopleNation(str1, 100);
                tbNation_Identity.Text = str1.ToString().Trim();                str1.Length = 0;
                str1.Append(str);
                iRet = GetPeopleSex(str1, 100);
                tbSex_Identity.Text = str1.ToString().Trim();
                    Pic_Identity_BM.Image = Image.FromFile("zp.bmp");
                CloseComm();
在这里把设备关闭掉了,可是重新使用再读卡也不用释放资源把,有点不明白啊

            }
            catch (Exception ex)
            {
                MessageBox.Show(this, ex.Message, "错误信息!", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1);
            }

解决方案 »

  1.   

    http://www.39g.com/html/dnet/cshare/2010/09/115194724942.htm
    希望是对你有帮助
      

  2.   

    像这样的外调函数一般都是C++语言写的,如果C#调用的话会因为参数类型不一致,弹出‘尝试读取写入受保护的内存。这通常指示其他内存已损坏’ 这个错误。通常解决办法是将他们的类型转换成一样的即可。比如从Int16转换成Int32之类的转换。你检查下你的类型转换吧!
      

  3.   

    Using还不是显式释放,不可已经可以了。显式释放要手动写GC
      

  4.   

    using  不是只能用于一个类吗???这个方法在L类的里面啊
      

  5.   

    应该怎么写,取决于你释放的非托管资源是什么,一般来说就是调用Win API完成资源清理,例如对于数据库资源资源你通常:
      if (disposing)
      {
      if (connection != null)
      connection.Dispose();
      }
    而对于文件资源,你可能
      if (fileHandle != IntPtr.Zero)
      {
      CloseHandle(fileHandle);
      fileHandle = IntPtr.Zero;
      }
      

  6.   

    ho ho ho ...
    google