/****************************************************************************** * 文件名称: CardReader.cs * 文件说明: 读卡的封装,包括社保卡,身份证,电子凭证等等 * 当前版本: V1.0 * 创建日期: 2022-06-20 * * * 2020-06-20: 增加 CardReader 类 * ***** 2020-06-20: 增加 CardReader 方法,获取URL地址,USER信息,地方版SSCard.dll使用 * ***** 2020-06-20: 增加 CardReader 方法重载,国家版电子凭证使用 * ***** 2020-06-20: 增加 Init 方法,SSCard环境初始化 * ***** 2020-06-20: 增加 ReadCardBas 方法,读社保卡 * ***** 2020-06-20: 增加 VerifyPIN 方法,验证密码 * ***** 2020-06-20: 增加 ChangePIN 方法,修改密码 * ***** 2020-06-20: 增加 ReadSFZ 方法,读身份证 * ***** 2020-06-20: 增加 GetQRBase 方法,读二维码 * ***** 2020-06-20: 增加 NationEcTrans 方法,读电子凭证(国家版) ******************************************************************************/ using Newtonsoft.Json; using Newtonsoft.Json.Linq; using PTMedicalInsurance.Helper; using PTMedicalInsurance.Variables; using System; using System.Runtime.InteropServices; using System.Text; namespace PTMedicalInsurance.CardReaders { //class CardReader //{ // const string DllPath = @"SSCard.dll"; // private bool initilaized = false; // [DllImport("SSCard.dll", EntryPoint = "Init", CharSet = CharSet.Ansi, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)] // static extern int Init(StringBuilder pURL, StringBuilder pUser); // [DllImport("SSCard.dll", EntryPoint = "ReadCardBas", CharSet = CharSet.Ansi, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)] // static extern int ReadCardBas(StringBuilder pOutBuff, int nOutBuffLen, StringBuilder pSignBuff, int nSignBuffLen); // //社保卡-异地1 // [DllImport("SSCardDriver.dll", EntryPoint = "iReadCardBas_HSM_Step1", CharSet = CharSet.Ansi, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)] // static extern int ReadCardBas_HSM_Step1(int iType, StringBuilder pDevInfo, StringBuilder pOutInfo); // //社保卡-异地2 // [DllImport("SSCardDriver.dll", EntryPoint = "iReadCardBas_HSM_Step2", CharSet = CharSet.Ansi, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)] // static extern int ReadCardBas_HSM_Step2(StringBuilder pKey, StringBuilder pOutInfo); // private string URL; // private string User; // public CardReader() // { // } // public CardReader(string URL, string User) // { // this.URL = URL; // this.User = User; // } // public int Init() // { // string errMsg = ""; // int result = -1; // try // { // StringBuilder sbURL = new StringBuilder(URL); // StringBuilder sbUSER = new StringBuilder(User); // result = Init(sbURL, sbUSER); // return result; // } // catch (Exception ex) // { // errMsg = ex.Message; // return result; // } // finally // { // Global.writeLog("初始化", URL + ":" + User, result.ToString() + ":" + errMsg); // } // } // public int ReadCardBas(out string basInfo, out string regInfo) // { // basInfo = ""; regInfo = ""; // int rtn = -1; // try // { // StringBuilder sbBasInfo = new StringBuilder(1024); // StringBuilder sbRegInfo = new StringBuilder(1024); // rtn = ReadCardBas(sbBasInfo, 1024, sbRegInfo, 1024); // basInfo = sbBasInfo.ToString(); // regInfo = sbRegInfo.ToString(); // return rtn; // } // catch (Exception ex) // { // basInfo = "ReadCardBas异常:" + ex.Message; // return rtn; // } // finally // { // Global.writeLog("读社保卡(" + URL + ")", regInfo, basInfo); // } // } // public int ReadCardBas_HSM_Step1(int iType, string sDevInfo, out string sOutInfo) // { // sOutInfo = ""; // int rtn = -1; // try // { // StringBuilder bDevInfo = new StringBuilder(sDevInfo); // StringBuilder bOutInfo = new StringBuilder(1024); // rtn = ReadCardBas_HSM_Step1(iType, bDevInfo, bOutInfo); // sOutInfo = bOutInfo.ToString(); // return rtn; // } // catch (Exception ex) // { // sOutInfo = "ReadCardBas_HSM_Step1异常:" + ex.Message; // return rtn; // } // finally // { // Global.writeLog("调用社保卡ReadCardBas_HSM_Step1函数:", iType + "|" + sDevInfo, sOutInfo); // } // } // public int ReadCardBas_HSM_Step2(string pKey, out string sOutInfo) // { // sOutInfo = ""; // int rtn = -1; // try // { // StringBuilder bPKey = new StringBuilder(pKey); // StringBuilder bOutInfo = new StringBuilder(1024); // rtn = ReadCardBas_HSM_Step2(bPKey, bOutInfo); // sOutInfo = bOutInfo.ToString(); // return rtn; // } // catch (Exception ex) // { // sOutInfo = "ReadCardBas_HSM_Step2异常:" + ex.Message; // return rtn; // } // finally // { // Global.writeLog("调用社保卡ReadCardBas_HSM_Step2函数:", pKey, sOutInfo); // } // } // /// // /// 读身份证 // /// // /// // /// // public int ReadSFZ(out string OutBuff) // { // OutBuff = ""; // try // { // SFZReader reader = new SFZReader(); // return reader.ReadSFZ(out OutBuff); // } // catch (Exception ex) // { // OutBuff = "ReadSFZ 异常:" + ex.Message; // return -1; // } // } // /// // /// 6101 // /// // /// // /// // public int ReadEC(out string OutBuff) // { // OutBuff = ""; // try // { // ECTokenData eCToken = new ECTokenData(); // eCToken.orgId = Global.inf.hospitalNO; // eCToken.operatorId = Global.user.ID; // eCToken.operatorName = Global.user.name; // eCToken.officeId = Global.user.officeID; // eCToken.officeName = Global.user.officeName; // eCToken.businessType = Global.businessType; // //eCToken.outBizNo = bizNo; // //eCToken.extData = ""; // string tmp = JsonConvert.SerializeObject(eCToken); // var inData = new { InData = JObject.Parse(tmp) }; // JObject joInData = new JObject( // new JProperty("InData", JObject.Parse(tmp)) // ); // ECReader reader = new ECReader(); // return reader.Read(joInData,out OutBuff); // } // catch (Exception ex) // { // OutBuff = "ReadEC 异常:" + ex.Message; // return -1; // } // } // /// // /// 6101 // /// // /// // /// // public int ECQuery(out string OutBuff) // { // OutBuff = ""; // try // { // EcQueryData ecqueryData = new EcQueryData(); // ecqueryData.orgId = Global.inf.hospitalNO; // ecqueryData.operatorId = Global.user.ID; // ecqueryData.operatorName = Global.user.name; // ecqueryData.officeId = Global.user.officeID; // ecqueryData.officeName = Global.user.officeName; // ecqueryData.businessType = Global.businessType; // //eCToken.outBizNo = bizNo; // //eCToken.extData = ""; // NationECInput nationECInput = new NationECInput(); // nationECInput.data = ecqueryData; // nationECInput.orgId = Global.inf.hospitalNO; // nationECInput.transType = "ec.query"; // nationECInput.extra = ""; // //测试环境电子凭证动态库地址:http://igb.hsa.gdgov.cn/tst_nation_eccode/tst_eccode/localcfc/api/hsecfc/localQrCodeQuery // //正式环境电子凭证动态库地址:http://hosp.gd.hsip.gov.cn/prd_nation_eccode/prd_eccode/localcfc/api/hsecfc/localQrCodeQuery // NationECCodeAPI nationECCodeAPI = new NationECCodeAPI(Global.inf.ecURL); // return nationECCodeAPI.NationEcTrans(nationECInput, out OutBuff); // } // catch (Exception ex) // { // OutBuff = "ECQuery 异常:" + ex.Message; // return -1; // } // } //} class CardReader:MarshalByRefObject { const string DllPath = @"SSCard.dll"; private bool initilaized = false; [DllImport("SSCard.dll", EntryPoint = "Init", CharSet = CharSet.Ansi, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)] static extern int Init(IntPtr pURL, IntPtr pUser); [DllImport("SSCard.dll", EntryPoint = "ReadCardBas", CharSet = CharSet.Ansi, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)] private static extern int ReadCardBas(IntPtr pOutBuff, int nOutBuffLen, IntPtr pSignBuff, int nSignBuffLen); [DllImport("SSCard.dll", EntryPoint = "VerifyPIN", CharSet = CharSet.Ansi, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)] static extern int VerifyPIN(StringBuilder pOutBuff, int nOutBuffLen); [DllImport("SSCard.dll", EntryPoint = "ChangePIN", CharSet = CharSet.Ansi, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)] static extern int ChangePIN(StringBuilder pOutBuff, int nOutBuffLen); [DllImport("SSCard.dll", EntryPoint = "ReadSFZ", CharSet = CharSet.Ansi, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)] static extern int ReadSFZ(StringBuilder pOutBuff, int nOutBuffLen, StringBuilder pSignBuff, int nSignBuffLen); [DllImport("SSCard.dll", EntryPoint = "GetQRBase", CharSet = CharSet.Ansi, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)] static extern int GetQRBase(int nTimeout, StringBuilder pOutBuff, int nOutBuffLen, StringBuilder pSignBuff, int nSignBuffLen); //电子凭证 [DllImport("NationECCode.dll", EntryPoint = "NationEcTrans", CharSet = CharSet.Ansi, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)] static extern IntPtr NationEcTrans(StringBuilder strUrl, StringBuilder InData, StringBuilder OutData); private static readonly Lazy _lazyInstance = new Lazy(() => new CardReader()); private string URL; private string User; private static CardReader _instance; private static readonly object _lock = new object(); public static int count =0; public static int countA = 0; public static int countinit = 0; private CardReader() { } public static CardReader Instance => _lazyInstance.Value; //public static CardReader Instance //{ // get // { // if (_instance == null) // { // lock (_lock) // { // if (_instance == null) // { // _instance = new CardReader(); // count++; // Global.writeLog_debug($"获取实例且创建实例:{count}"); // } // } // } // else // { // countA++; // Global.writeLog_debug($"检测到实例已创建,不再重复创建:{countA}"); // } // return _instance; // } //} public void Initialize(string url, string user) { lock (_lock) { if (string.IsNullOrEmpty(URL) && string.IsNullOrEmpty(User)) { URL = url; User = user; } else { //throw new InvalidOperationException("CardReader 已经初始化,无法重复设置 URL 和 User。"); } } } private CardReader(string URL, string User) { this.URL = URL; this.User = User; } public int Init() { if (initilaized) { Global.writeLog_debug("检测到已经初始化,本次不再初始化!"); return 0; } countinit++; Global.writeLog_debug($"开始初始化:{countinit}"); string errMsg = ""; int result = -1; //Global.writeLog_debug(string.Format("读卡初始化:{0},{1}", URL, User)); // 将托管字符串转换为 ANSI 编码的字节数组 byte[] urlBytes = Encoding.ASCII.GetBytes(URL + '\0'); // 添加终止符 byte[] userBytes = Encoding.ASCII.GetBytes(User + '\0'); // 添加终止符 //// 分配非托管内存并复制字符串数据 //IntPtr pUrl = Marshal.AllocCoTaskMem(urlBytes.Length); //IntPtr pUser = Marshal.AllocCoTaskMem(userBytes.Length); // 分配全局非托管内存并复制字符串数据 IntPtr pUrl = Marshal.AllocHGlobal(urlBytes.Length); IntPtr pUser = Marshal.AllocHGlobal(userBytes.Length); try { // 将托管字节数组复制到非托管内存 Marshal.Copy(urlBytes, 0, pUrl, urlBytes.Length); Marshal.Copy(userBytes, 0, pUser, userBytes.Length); result = Init(pUrl, pUser); initilaized = true; return result; } catch (Exception ex) { errMsg = ex.Message; return result; } finally { Global.writeLog_debug("初始化", $"countinit:{countinit}", result.ToString() + ":" + errMsg); //// 显式释放非托管内存 //if (pUrl != IntPtr.Zero) Marshal.FreeCoTaskMem(pUrl); //if (pUser != IntPtr.Zero) Marshal.FreeCoTaskMem(pUser); // 显式释放全局非托管内存 if (pUrl != IntPtr.Zero) Marshal.FreeHGlobal(pUrl); if (pUser != IntPtr.Zero) Marshal.FreeHGlobal(pUser); } } /// /// 读社保卡 /// /// /// public int ReadCardBas(out string basInfo) { basInfo = ""; int rtn = -1; // 分配非托管内存 //IntPtr pOutBuff = Marshal.AllocCoTaskMem(1024); //IntPtr pSignBuff = Marshal.AllocCoTaskMem(8192); // 分配全局非托管内存 IntPtr pOutBuff = Marshal.AllocHGlobal(1024); IntPtr pSignBuff = Marshal.AllocHGlobal(8192); try { rtn = ReadCardBas(pOutBuff, 1024, pSignBuff, 8192); if (rtn == 0) { // 解析返回读卡信息 string outString = Marshal.PtrToStringAnsi(pOutBuff); string signString = Marshal.PtrToStringAnsi(pSignBuff); basInfo = outString; Global.pat.card.BusinessCode = signString; } else { string outString = Marshal.PtrToStringAnsi(pOutBuff); basInfo = outString; } return rtn; } catch (Exception ex) { basInfo = "ReadCardBas异常:" + ex.Message; return rtn; } finally { Global.writeLog("读社保卡", "", basInfo); //// 显式释放非托管内存 //Marshal.FreeCoTaskMem(pOutBuff); //Marshal.FreeCoTaskMem(pSignBuff); // 显式释放非托管内存 Marshal.FreeHGlobal(pOutBuff); Marshal.FreeHGlobal(pSignBuff); } } public int ReadCardBas(out string basInfo, out string regInfo) { basInfo = "";regInfo = ""; int rtn = -1; // 分配非托管内存 //IntPtr pOutBuff = Marshal.AllocCoTaskMem(1024); //IntPtr pSignBuff = Marshal.AllocCoTaskMem(8192); // 分配全局非托管内存 IntPtr pOutBuff = Marshal.AllocHGlobal(1024); IntPtr pSignBuff = Marshal.AllocHGlobal(8192); try { rtn = ReadCardBas(pOutBuff, 1024, pSignBuff, 8192); if (rtn == 0) { // 解析返回读卡信息 string outString = Marshal.PtrToStringAnsi(pOutBuff); string signString = Marshal.PtrToStringAnsi(pSignBuff); basInfo = outString; regInfo = signString; Global.pat.card.BusinessCode = signString; } else { string outString = Marshal.PtrToStringAnsi(pOutBuff); string signString = Marshal.PtrToStringAnsi(pSignBuff); basInfo = outString; regInfo = signString; } return rtn; } catch (Exception ex) { basInfo = "ReadCardBas异常:" + ex.Message; return rtn; } finally { Global.writeLog("读社保卡", "", basInfo); //// 显式释放非托管内存 //Marshal.FreeCoTaskMem(pOutBuff); //Marshal.FreeCoTaskMem(pSignBuff); // 显式释放非托管内存 Marshal.FreeHGlobal(pOutBuff); Marshal.FreeHGlobal(pSignBuff); } } /// /// 读身份证 /// /// /// public int ReadSFZ(out string OutBuff) { OutBuff = ""; int rtn = -1; try { StringBuilder sbOutBuff = new StringBuilder(1024); StringBuilder sbBusiCardBuff = new StringBuilder(1024); rtn = ReadSFZ(sbOutBuff, 1024, sbBusiCardBuff, 1024); // 解析返回读卡信息 OutBuff = sbOutBuff.ToString(); Global.pat.card.BusinessCode = sbBusiCardBuff.ToString(); return rtn; } catch (Exception ex) { OutBuff = "ReadSFZ 异常:" + ex.Message; return rtn; } } public int ReadECToken(string URL, string inputParam, out string sOutPar) { sOutPar = ""; StringBuilder sbURL = new StringBuilder(URL); StringBuilder sbInput = new StringBuilder(inputParam); StringBuilder sbOut = new StringBuilder(40960); IntPtr pInt = CardReader.NationEcTrans(sbURL, sbInput, sbOut); string outputData = sbOut.ToString(); //sOutPar = parseECTokenOutput(outputData); sOutPar = outputData; if (JsonHelper.getDestValue(JObject.Parse(outputData), "code") != "0") { return -1; } return 0; } /// /// 6101 /// /// /// public int ECQuery(out string OutBuff) { OutBuff = ""; try { EcQueryData ecqueryData = new EcQueryData(); ecqueryData.orgId = Global.inf.hospitalNO; ecqueryData.operatorId = Global.user.ID; ecqueryData.operatorName = Global.user.name; ecqueryData.officeId = Global.user.officeID; ecqueryData.officeName = Global.user.officeName; ecqueryData.businessType = Global.businessType; //eCToken.outBizNo = bizNo; //eCToken.extData = ""; NationECInput nationECInput = new NationECInput(); nationECInput.data = ecqueryData; nationECInput.orgId = Global.inf.hospitalNO; nationECInput.transType = "ec.query"; nationECInput.extra = ""; //测试环境电子凭证动态库地址:http://igb.hsa.gdgov.cn/tst_nation_eccode/tst_eccode/localcfc/api/hsecfc/localQrCodeQuery //正式环境电子凭证动态库地址:http://hosp.gd.hsip.gov.cn/prd_nation_eccode/prd_eccode/localcfc/api/hsecfc/localQrCodeQuery NationECCodeAPI nationECCodeAPI = new NationECCodeAPI(Global.inf.ecURL); return nationECCodeAPI.NationEcTrans(nationECInput, out OutBuff); } catch (Exception ex) { OutBuff = "ECQuery 异常:" + ex.Message; return -1; } } public static string parseECTokenOutput(string data) { JObject joRtn = JObject.Parse(data); Global.pat.ecToken = JsonHelper.getDestValue(joRtn, "data.ecToken"); Global.pat.certNO = JsonHelper.getDestValue(joRtn, "data.idNo"); //身份证 Global.pat.name = JsonHelper.getDestValue(joRtn, "data.userName"); Global.pat.certType = JsonHelper.getDestValue(joRtn, "data.idType"); Global.pat.insuplc_admdvs = JsonHelper.getDestValue(joRtn, "data.insuOrg"); // 令牌 Global.pat.mdtrtcertNO = Global.pat.ecToken; return data; } /// /// 解析读卡结果 /// /// /// //private string parseCardInfo(string inBuff, int startIndex = 1) //{ // // 360100 | 362502198603060820 | B04D4C6B2 | 360100D156000005B04D4C6BF99AC1BD | 李凌 | 0081544C9386841907267A0FD6 | 2.00 | 20200612 | 20300612 | 369900906440 || // string[] data = inBuff.Split("|".ToCharArray()); // CardInfo card = new CardInfo(); // card.certno = data[startIndex + 1]; // card.cardno = data[startIndex + 2]; // card.card_sn = data[startIndex + 3]; // card.psn_name = data[startIndex + 4]; // Global.pat.insuplc_admdvs = data[startIndex]; //行政区划 // Global.pat.card.SN = card.card_sn; // Global.pat.certType = "01"; // Global.pat.certNO = card.certno; // Global.pat.name = card.psn_name; // Global.pat.card.NO = card.cardno; // Global.pat.mdtrtcertNO = card.certno; // string outParam = JsonHelper.toJsonString(card); // Global.writeLog("读卡返回:", inBuff, outParam); // return outParam; //} } class CardReaderBySSCardDriver { [DllImport("SSCardDriver.dll", EntryPoint = "iReadCardUnclassifiedBas", CharSet = CharSet.Ansi, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)] static extern int ReadCardUnclassifiedBas(int iType, IntPtr pOutInfo); [DllImport("SSCardDriver.dll", EntryPoint = "iReadSFZ", CharSet = CharSet.Ansi, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)] static extern int ReadSFZ(StringBuilder pOutInfo); [DllImport("SSCardDriver.dll", EntryPoint = "iGetQRBase", CharSet = CharSet.Ansi, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)] static extern int GetQRBase(int TimeOut, IntPtr pOutInfo); public int ReadCardUnclassifiedBas(int iType, out string basInfo) { basInfo = ""; int rtn = -1; // 分配非托管内存 //IntPtr pOutBuff = Marshal.AllocCoTaskMem(1024); //IntPtr pSignBuff = Marshal.AllocCoTaskMem(8192); // 分配全局非托管内存 IntPtr pOutBuff = Marshal.AllocHGlobal(1024); try { rtn = ReadCardUnclassifiedBas(iType, pOutBuff); if (rtn == 0) { // 解析返回读卡信息 basInfo = Marshal.PtrToStringAnsi(pOutBuff); } else { basInfo = Marshal.PtrToStringAnsi(pOutBuff); } return rtn; } catch (Exception ex) { basInfo = "ReadCardUnclassifiedBas异常:" + ex.Message; return rtn; } finally { Global.writeLog("读社保卡", "", basInfo); //// 显式释放非托管内存 //Marshal.FreeCoTaskMem(pOutBuff); //Marshal.FreeCoTaskMem(pSignBuff); // 显式释放非托管内存 Marshal.FreeHGlobal(pOutBuff); } } /// /// 读身份证 /// /// /// public int ReadSFZ(out string OutBuff) { OutBuff = ""; int rtn = -1; try { StringBuilder sbOutBuff = new StringBuilder(1024); rtn = ReadSFZ(sbOutBuff); // 解析返回读卡信息 OutBuff = sbOutBuff.ToString(); return rtn; } catch (Exception ex) { OutBuff = "ReadSFZ 异常:" + ex.Message; return rtn; } } public int GetQRBase(int TimeOut, out string basInfo) { basInfo = ""; int rtn = -1; // 分配全局非托管内存 IntPtr pOutBuff = Marshal.AllocHGlobal(1024); try { rtn = GetQRBase(TimeOut, pOutBuff); if (rtn == 0) { // 解析返回读卡信息 basInfo = Marshal.PtrToStringAnsi(pOutBuff); } else { basInfo = Marshal.PtrToStringAnsi(pOutBuff); } return rtn; } catch (Exception ex) { basInfo = "GetQRBase:" + ex.Message; return rtn; } finally { Global.writeLog("读社保卡", "", basInfo); //// 显式释放非托管内存 //Marshal.FreeCoTaskMem(pOutBuff); //Marshal.FreeCoTaskMem(pSignBuff); // 显式释放非托管内存 Marshal.FreeHGlobal(pOutBuff); } } } /// /// 华大内嵌读卡器 /// class CardReaderByHdEmb { [DllImport("SSSE32.dll", EntryPoint = "ICC_Reader_Open", CharSet = CharSet.Ansi, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)] static extern int ICC_Reader_Open(IntPtr pDevName); [DllImport("SSSE32.dll", EntryPoint = "iReadCardBas", CharSet = CharSet.Ansi, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)] static extern int ReadCardBas(int iType, IntPtr pOutInfo); public int ICC_Reader_Open(string devName, out string error) { error = ""; int rtn = -1; // 分配全局非托管内存 IntPtr pOutBuff = Marshal.StringToHGlobalAnsi(devName); try { rtn = ICC_Reader_Open(pOutBuff); if (rtn == 0) { error = "端口打开成功"; } else { error = Marshal.PtrToStringAnsi(pOutBuff) + "端口打开失败"; } return rtn; } catch (Exception ex) { error = "打开端口异常:" + ex.Message; return rtn; } finally { Global.writeLog("打开端口", devName, error); // 显式释放非托管内存 Marshal.FreeHGlobal(pOutBuff); } } public int ReadCardBas(int iType, out string basInfo) { basInfo = ""; int rtn = -1; // 分配非托管内存 //IntPtr pOutBuff = Marshal.AllocCoTaskMem(1024); //IntPtr pSignBuff = Marshal.AllocCoTaskMem(8192); // 分配全局非托管内存 IntPtr pOutBuff = Marshal.AllocHGlobal(1024); try { rtn = ReadCardBas(iType, pOutBuff); if (rtn == 0) { // 解析返回读卡信息 basInfo = Marshal.PtrToStringAnsi(pOutBuff); } else { basInfo = Marshal.PtrToStringAnsi(pOutBuff); } return rtn; } catch (Exception ex) { basInfo = "ReadCardBas:" + ex.Message; return rtn; } finally { Global.writeLog("读社保卡", "", basInfo); // 显式释放非托管内存 Marshal.FreeHGlobal(pOutBuff); } } } }