c#里人怎么样使用二代身份证阅读器

.Net技术 码拜 5年前 (2016-02-23) 940次浏览
现在需要开发一个学生证明打印系统,学生只要用身份证一扫,就能自动打印出来,所用阅读器是精伦IDR200身份证阅读器,已经获得二次开发包,但在开发时,遇到了如下问题:
函数ReadBaseMsg的原型为:(c++定义,被封装在DLL文件里)
原    型:int ReadBaseMsg( unsigned char * pMsg, int * len);
说    明:本函数用于读取卡中基本信息,包括文字信息与图像信息。文字信息已经分段解析,输出格式为单字节,且每一字段信息已经被表示为字符串。图象信息被解码后存为文件photo.bmp(在当前工作目录下)。
参    数:
pMsg  [out] 无符号字符指针,指向读到的文本信息。需要在调用时分配内存,字节数不小于192。函数调用成功后,各字段的文本信息已经转换为单字节形式,并表示为字符串格式。
//申明
[DllImport(“sdtapi.dll”, EntryPoint = “ReadBaseMsg”, CharSet = CharSet.Ansi)]
public static extern int ReadBaseMsg(out string pMsg, out int len);
//使用
String  pMsg = “”;
int len = 0;
int result = ReadBaseMsg(out pMsg,out len);

运行后,报错:“尝试读取或写入受保护的内存”,不知怎么样解决。
而使用函数ReadBaseInfosPhoto:
原    型4:int ReadBaseInfosPhoto( char * Name, char * Gender, char * Folk,char *BirthDay, char * Code, char * Address,char *Agency, char * ExpireStart,char* ExpireEnd,char * directory)
说    明:本函数用于读取卡中基本信息,包括文字信息与图像信息。文字信息以字符串格式输出。图象信息被解码后存为照片photo.bmp和photo.jpg,身份证正面图片1.jpg,身份证反面图片2.jpg(在directory指定目录下)。
//申明:
[DllImport(“sdtapi.dll”, EntryPoint = “ReadBaseInfosPhoto”, CharSet = CharSet.Ansi)]
public static extern int ReadBaseInfos(out string Name, out string Gender, out string Folk, out string BirthDay, out string Code, out string Address, out string Agency, out string ExpireStart, out string ExpireEnd,string dir);
//使用:
String name;
//….
Int result = ReadBaseInfos(out Name, out Gender, out Folk, out BirthDay, out Code, out Address, out Agency, out ExpireStart, out ExpireEnd,  “d:/photo”);
倒是不报错了,但无法正确读出信息,返回值显示:目录错误.不知道是什么意思,那个d:/photo是正确设置的,有的,按照说明设置成null值(指当前目录),仍然是“目录错误”.不知道这个目录是什么目录. 运行后在指定目录里出现一个photo.wlt文件,只有1KB,不知是什么格式。
问一下,有没有人在C#里做过这种项目?阅读器请高手指点?能不能提供一点实例?多谢!
解决方案

10

目录路径应该这样设置:
@”D:\photo”
或”D:\photo”
不要把本地路径跟URL路径弄混了

5

unsigned char * pMsg  换成 IntPtr pMsg

25

ReadBaseMsg 在说明中已经说了,返回值 msg是需要事先分配内存的。
那么你就要先申明一个区域用来存放它的返回值,由于是非托管的,你可以先申请非托管内存

        public static extern int ReadBaseMsg(IntPtr pMsg, out int len);
            IntPtr p = System.Runtime.InteropServices.Marshal.AllocHGlobal(4096);
            int len = 0;
            ReadBaseMsg(p, out len);
            string msg = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(p, len);
            System.Runtime.InteropServices.Marshal.FreeHGlobal(p);

试试这样行不行。

10

[DllImport(“sdtapi.dll”, EntryPoint = “ReadBaseMsg”, CharSet = CharSet.Ansi)]
public static extern int ReadBaseMsg(byte[] pMsg, ref int len);
或是加个unsafe
[DllImport(“sdtapi.dll”, EntryPoint = “ReadBaseMsg”, CharSet = CharSet.Ansi)]
public static unsafe extern int ReadBaseMsg(byte* pMsg,  int* len);
调用时
var bin = new byte[198];
int len=0;
ReadBaseMsg(&bin,&len);

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明c#里人怎么样使用二代身份证阅读器
喜欢 (0)
[1034331897@qq.com]
分享 (0)