OPOS DirectIO event review This may be a poor title name. So I'm basing what I did from this website.

The idea is though that I have made a lot of work to a Service Object for a OPOS MSR device. (useless detail) One of the DirectIO calls gets some data off of a card and was supposed to return a byte array. That ended up being a big mistake because Unicode and translating was just a big big BIG headache. So my suggestion was to just convert the byte array to a string in C++ then send fire a DirectIO event with said string and call it good. So I did that, and it appears to work. One thing that has me concerned though is one of the lines from that website


  The general rule to COM resource is, if you allocate it then you release it. The only exception is when a value is passed over a COM interface as an OUT param. In that case, the receiver of the value is responsible for releasing the resource


but I'm rather proud of my code none the less. I'll post my SO code and my mock up OPOS code (a test for me to show it works)

LONG ReaderHelper::ULCRead(LPVOID param)
{
    BYTE* bTmp = new BYTE[4];
    //a call to fill said bTmp with error checking and so forth
    CString str;
    for (int i = 0; i &lt; 4; i++)
    {
        str.AppendFormat( _T("%02X"), bTmp[i]);
    }
    delete[] bTmp;
    BSTR bstring = str.AllocSysString();
    LONG data = str.GetLength();
    USNMSRRFID* pso = (USNMSRRFID*)param;
    COPOSMSR msr(pso-&gt;mlpDispatch);
    msr.SODirectIO(0, &amp;data, &amp;bstring);
    SysFreeString(bstring);
    msr.ReleaseDispatch();
}


MOCK UP OPOS
yes it is ugly, sorry

    void msr_DirectIOEvent(int EventNumber, ref int pData, ref string pString)
    {
        Console.WriteLine();
        Console.WriteLine("\t\t&lt;{0}&gt;&lt;{1}&gt;&lt;{2}&gt;:Len:{4}&lt;{3}&gt;", EventNumber, pData,pString, GetHexBytes(pString), pString.Length);
        Console.WriteLine();
    }
    string GetHexBytes(string str)
    {
        var bytes = System.Text.UnicodeEncoding.Unicode.GetBytes(str);
        string strbytes = "";
        foreach (byte b in bytes)
            strbytes += string.Format("{0}:", b.ToString("X2"));

        return strbytes;
    }


yields me this

2013-02-12.21:59:30 #Page:3#
2013-02-12.21:59:30     ULCRead(4)-00:00:00:00:
            &lt;0&gt;&lt;8&gt;&lt;00000000&gt;:Len:8&lt;30:00:30:00:30:00:30:00:30:00:30:00:30:00:30:00:&gt;
2013-02-12.21:59:30 #Page:4#
2013-02-12.21:59:30     ULCRead(4)-9D:5A:AD:47:
            &lt;0&gt;&lt;8&gt;&lt;9D5AAD47&gt;:Len:8&lt;39:00:44:00:35:00:41:00:41:00:44:00:34:00:37:00:&gt;
2013-02-12.21:59:30 #Page:5#
2013-02-12.21:59:30     ULCRead(4)-5D:E3:EC:93:
            &lt;0&gt;&lt;8&gt;&lt;5DE3EC93&gt;:Len:8&lt;35:00:44:00:45:00:33:00:45:00:43:00:39:00:33:00:&gt;
This BYTE* bTmp = new BYTE[4]; could just be put on the stack with BYTE bTmp[4]; (the proper term is actually automatic storage duration which in most cases means it ends up on the stack). This normally avoids a call to malloc and you don't have to delete it explicitly.
I'm not too versed in COM programming but if msr.SODirectIO(0, &amp;data, &amp;bstring); could throw an exception you might want to wrap it into a try {} finally {} in order to ensure the cleanup of the BSTR and COM resource is done regardless.
I know it's just a quick mockup but GetHexBytes could be reduced by using Linq:

string GetHexBytes(string str)
{
    var bytes = System.Text.UnicodeEncoding.Unicode.GetBytes(str);
    var hexBytes = bytes.Select(b =&gt; b.ToString("X2")).ToArray();
    return string.Join(":", hexBytes);
}