日期:2014-05-16 浏览次数:20616 次
最近在做一个项目,其中涉及到身份证的读取问题,用的是新中二代身份证的读卡器,厂商有发送过来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