Writing data to a datacard using the IBidiSpl interface

那年仲夏 提交于 2020-05-13 20:22:41

问题


I'm developing a C # application to write data to smartcards through the Datacard SD360 printer.

After downloading the SDK provided by the manufacturer (at this link: https://www.datacard.com/id-card-printer-support-and-drivers/sd360-id-card-printer#drivers-and-downloads), I encountered some issues with the IBidiSpl Interface, used in the SDK examples.

I am using the SendRecv method to send data to the printer, however the xml returned always brings the CDATA [] field empty.

public string SendRecv(string action, string actionType, string data) {
        IntPtr dataPointer = default(IntPtr);
        IntPtr dataTypePointer = default(IntPtr);
        IntPtr sizePointer = default(IntPtr);
        IntPtr pointerToDataPointer = default(IntPtr);
        IntPtr tempResultPointer = default(IntPtr);
        IntPtr countPointer = default(IntPtr);
        IntPtr resultPointer = default(IntPtr);

        string xml = string.Empty;

        try {
            BidiRequest bidiRequest = (BidiRequest) Activator.CreateInstance(typeof(BidiRequest), true);
            IBidiRequest iBidiRequest = (IBidiRequest) bidiRequest;

            iBidiRequest.SetSchema(action);

            // Set the input data for the request, if any
            if (data.Length != 0) {
                dataPointer = Marshal.AllocCoTaskMem(data.Length * sizeof(char));
                var chars = data.ToCharArray();
                Marshal.Copy(chars, 0, dataPointer, data.Length);
                iBidiRequest.SetInputData((UInt32) BIDI_TYPE.BIDI_BLOB, dataPointer, (UInt32) data.Length * sizeof(char));
            }

            // Send request to driver
            var val = _iBidiSpl.SendRecv(actionType, iBidiRequest);

            // Check if request was a success
            resultPointer = Marshal.AllocCoTaskMem(sizeof(Int32));

            // Call the method
            iBidiRequest.GetResult(resultPointer);

            // Get the value
            Int32 result = (Int32) Marshal.PtrToStructure(resultPointer, typeof(Int32));

            const int resultSuccess = 0;
            if (result == resultSuccess) {
                // Check if any data was returned. Note: dxp01sdk.strings.ENDJOB
                // and dxp01sdk.strings.PRINTER_ACTION do not return any values.

                // First allocate memory
                countPointer = Marshal.AllocCoTaskMem(sizeof(Int32));

                // Call the method
                iBidiRequest.GetEnumCount(countPointer);

                // Get the value
                Int32 count = (Int32) Marshal.PtrToStructure(countPointer, typeof(Int32));
                if (count != 0) {
                    // Driver sent some data. Now retrieve the data sent by the driver

                    // First allocate memory for type and size
                    dataTypePointer = Marshal.AllocCoTaskMem(sizeof(Int32));
                    sizePointer = Marshal.AllocCoTaskMem(sizeof(Int32));

                    // Now allocate memory for data. Also add level of indirection.
                    IntPtr ptrTemp = default(IntPtr);
                    pointerToDataPointer = Marshal.AllocCoTaskMem(sizeof(Int32));
                    Marshal.StructureToPtr(ptrTemp, pointerToDataPointer, false);

                    // Finally, retrieve the data sent by the driver
                    string schema = string.Empty;
                    iBidiRequest.GetOutputData(0, schema, dataTypePointer, pointerToDataPointer, sizePointer);

                    // Get the size of the data in bytes returned from SendRecv method.
                    Int32 size = (Int32) Marshal.PtrToStructure(sizePointer, typeof(Int32));

                    // Get the data itself. First remove level of indirection
                    tempResultPointer = Marshal.ReadIntPtr(pointerToDataPointer);

                    // Get Unicode string from pointer. Unicode characters are 16-bit characters.
                    // size contains the number of bytes returned by SendRecv method
                    xml = Marshal.PtrToStringUni(tempResultPointer, size / sizeof(char));
                }
            }
        }
        finally {
            Marshal.FreeCoTaskMem(dataPointer);
            Marshal.FreeCoTaskMem(sizePointer);
            Marshal.FreeCoTaskMem(dataTypePointer);
            Marshal.FreeCoTaskMem(pointerToDataPointer);
            Marshal.FreeCoTaskMem(tempResultPointer);
            Marshal.FreeCoTaskMem(countPointer);
            Marshal.FreeCoTaskMem(resultPointer);
        }
        return xml;
    }

XML returned:

<PrinterStatus>
<ClientID>{790F025E-EB9D-44A6-AF38-35B7DD7C046A}</ClientID>
<WindowsJobID>0</WindowsJobID>
<PrinterJobID>3094</PrinterJobID>
<ErrorCode>0</ErrorCode>
<ErrorSeverity>0</ErrorSeverity>
<ErrorString></ErrorString>
<DataFromPrinter><![CDATA[]]></DataFromPrinter>
</PrinterStatus>

Anyone who has ever used the IBidiSpl interface or already made an application for some Datacard printer would have an idea of what might be happening?

来源:https://stackoverflow.com/questions/46569964/writing-data-to-a-datacard-using-the-ibidispl-interface

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!