日期:2014-05-16  浏览次数:20595 次

尝试读取或写入受保护的内存。这通常指示其他内存已损坏 ,新中二代身份证读取 Syn_ReadMsg,Syn_ReadBaseMsg(一)

    最近在做一个项目,其中涉及到身份证的读取问题,用的是新中二代身份证的读卡器,厂商有发送过来DLL,可是一调用,开始时读取信息很成功,但是,没几次程序就崩毁了,有时候直接就关闭,有时候就跳出错误提示:尝试读取或写入受保护的内存。这通常指示其他内存已损坏,出错的函数是Syn_ReadMsg,

    原型:

    [DllImport("SynIDCardAPI.dll", EntryPoint = "Syn_ReadMsg", CharSet = CharSet.Ansi)]        

    public static extern int Syn_ReadMsg(int iPortID, int iIfOpen, ref IDCardData pIDCardData); 

   被这个几乎要弄到吐血,网上搜答案看到很多同学都遇到过这样的问题。给我启发最大的是一个说New 一个Image,但是Syn_ReadMsg()里面没有new Image 的啊,百思不得其解。,然后继续找,最后有一个方案说是用Syn_ReadBaseMsg代替Syn_ReadMsg,我用这个方案,果然不会报错。

附上源码:这个是使用Syn_ReadBaseMsg来读取身份证信息,读取到的信息文字跟图片是分别存放在两个指针里的,如果要获取图片信息,得另行处理。如果只是仅仅想读取身份证的文字信息的话,可以使用下面的函数

        int port;//端口号       
        string baut;//波特率
        string passporInfo;//读身份证后返回的信息
       
        /// <summary>
        /// 获取身份证信息
        /// </summary>     
        public string GetPassPortInfo()
        {
            passporInfo = null;

            #region 自动寻找读卡器
          
            int i, nRet;
            uint[] iBaud = new uint[1];
            i = Syn_FindReader(); //自动寻找读卡器 返回值:0未找到 其他	串口1~16 USB:1001~1016

            if (i > 0)
            {
                port = i;
                if (port < 1000)
                {
                    System.Threading.Thread.Sleep(200);
                    nRet = Syn_GetCOMBaud(port, ref iBaud[0]);//该函数只用于SAM采用RS232串口的情形,如果采用USB接口则不支持该API,此处端口号必须为1-16,表示串口。                                  
                    baut = Convert.ToString(iBaud[0]);
                }
            }
            else
            {
                //stmp = Convert.ToString(System.DateTime.Now) + "  没有找到身份证读卡器";
               // MessageBox.Show(stmp);
                return;
            }
            #endregion

            IDCardData CardMsg = new IDCardData();
            int Ret;
            byte[] pucIIN = new byte[4];
            byte[] pucSN = new byte[8];
            string errStr;

            if (Syn_OpenPort(port) == 0)
            {
                if (Syn_SetMaxRFByte(port, 80, 0) == 0)
                {
                    Ret = Syn_StartFindIDCard(port, ref pucIIN[0], 0); //开始找卡 iIfOpen:0表示不在该函数内部打开和关闭串口,此时确保之前调用了Syn_OpenPort来打开端口
                    Ret = Syn_SelectIDCard(port, ref pucSN[0], 0);//选卡

                    string cardMsg = new string(' ', 256);  //身份证基本信息返回长度为256
                    string imgMsg = new string(' ', 1024);  //身份证图片信息返回长度为1024
                    IntPtr msg = Marshal.StringToHGlobalAnsi(cardMsg);  //无符号字符指针,指向读到的文字信息。
                    uint mLen = 0; // 无符号整型数指针,指向读到的文字信息长度。
                    IntPtr img = Marshal.StringToHGlobalAnsi(imgMsg);   //身份证图片
                    uint iLen = 0;//无符号整型数指针,指向读到的照片信息长度。
                    try