高级语言调用C接口(二)回调函数(3)C#

发布于:2025-04-16 ⋅ 阅读:(20) ⋅ 点赞:(0)

原接口定义请参照高级语言调用C接口(二)回调函数(2)

我们直接来看C#的接口定义

        [DllImport("XXX.dll")]
        public static extern IntPtr Init(string pcPayDeviceIP, int usTlsPort, OnPayResult onPayResult);

委托定义

    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    public delegate void OnPayResult(IntPtr pstPayResult);

委托绑定接口及调用

OnPayResult onPayResult += new OnPayResult(OnPayResult);
Init(pcPayDeviceIP, usTlsPort, onPayResult);

接口定义

        
        protected abstract void PayResult(PayResult payResult);
        private void OnPayResult(IntPtr pstPayResult)
        {
            PayResultTmp st = (PayResultTmp)Marshal.PtrToStructure(pstPayResult, typeof(PayResultTmp));
            PayResult payResult = new PayResult();
            payResult.place = enPlace.SD_D_PLACE_BUTT;
            payResult.place = (enPlace)Marshal.ReadInt32(pstPayResult);
            payResult.errCode = PtrToUtf8String(st.errCode);
            payResult.errInfo = PtrToUtf8String(st.errInfo);
            payResult.seqId = PtrToUtf8String(st.seqId);
            payResult.merOrderId = PtrToUtf8String(st.merOrderId);
            payResult.srcReserve = PtrToUtf8String(st.srcReserve);
            payResult.attachedData = PtrToUtf8String(st.attachedData);
            payResult.totalAmount = PtrToUtf8String(st.totalAmount);
            payResult.couponAmount = PtrToUtf8String(st.couponAmount);
            payResult.payAmount = PtrToUtf8String(st.payAmount);
            payResult.payTime = PtrToUtf8String(st.payTime);
            payResult.orderCreateTime = PtrToUtf8String(st.orderCreateTime);
            payResult.status = PtrToUtf8String(st.status);
            PayResult(payResult);
        }

由于回调传过来的C申请的内存,结构与C#不一致,必须通过Marshal进行转换,否则会出现内存访问异常。

结构体定义

        [StructLayout(LayoutKind.Sequential)]
        private struct PayResultTmp
        {
            public enPlace place; //收单机构
            public IntPtr errCode; //错误码
            public IntPtr errInfo; //错误信息
            public IntPtr seqId; //平台流水号
            public IntPtr merOrderId; //商户订单号
            public IntPtr srcReserve; //请求系统预留字段
            public IntPtr attachedData; //商户附加数据
            public IntPtr totalAmount; //订单金额
            public IntPtr couponAmount; //优惠金额
            public IntPtr payAmount; //实付金额
            public IntPtr payTime; //支付时间
            public IntPtr orderCreateTime; //订单创建时间
            public IntPtr status; //交易状态
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct PayResult
        {
            public enPlace place; //收单机构
            public string errCode; //错误码
            public string errInfo; //错误信息
            public string seqId; //平台流水号
            public string merOrderId; //商户订单号
            public string srcReserve; //请求系统预留字段
            public string attachedData; //商户附加数据
            public string totalAmount; //订单金额
            public string couponAmount; //优惠金额
            public string payAmount; //实付金额
            public string payTime; //支付时间
            public string orderCreateTime; //订单创建时间
            public string status; //交易状态
        }

实现、通过继承抽象类,重写抽象接口实现回调的具体逻辑

        protected override void PayResult(PayResult payResult)
        {
            Console.WriteLine("errCode:{0}, errInfo:{1}", payResult.errCode, payResult.errInfo);
        }