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