Search code examples
c++bstropos

OPOS BSTR* not converting properly


So after a bunch of research I found that using WideCharToMultiByte worked great for sending data from the Control Object through OPOS to my custom SO. well we encountered a bug. In the DirectIO portion the C# Control Object's map is DirectIO(int command, ref int data, ref string object);

and for the longest we only needed to send simple commands through DirectIO. For instance to turn on the LED we would set the data to be the length in milleseconds, and the object to be the color. When we needed to write data to a tag or a card the text had to be parsed from a special XML styled string to a byte array... well now the need has come about that we need to have a byte array, use ASCII encoding to put that array into string form, and have it write..

The problem comes around that when I convert this string in my Service Object it doesn't convert it right. it seems to stop on null, even though SysStringLen knows the length is 4bytes. example The control object does this

        int page = 16;
        byte[] data = new byte[] { 0x19, 0x00, 0x30, 0x00 };
        string pData = System.Text.ASCIIEncoding.ASCII.GetString(data);
        msr.DirectIO(902, ref page, ref pData);

The SO sees this

int len = (int)SysStringLen(*pString);
long dataData = *pData;
char* dataObject = new char[1+len];

WideCharToMultiByte(CP_ACP, 0, *pString, -1, dataObject, len, NULL, NULL);
ByteUtil::LogArray("dataObject", (BYTE*)dataObject, len);

yields the output of

dataObject(4)-19:00:00:00

basically as soon as teh first null character is reached the rest of the data is lost. now if i convert the number from a string to a string it works out ok because I have a ByteUtil function just for that occasion... but it doesn't seem right for me to have to do that... why can't i just have it as a BYTE array?


Solution

  • Very easy, just change this line:

    WideCharToMultiByte(CP_ACP, 0, *pString, -1, dataObject, len, NULL, NULL);
    

    into:

    WideCharToMultiByte(CP_ACP, 0, *pString, len, dataObject, len, NULL, NULL);
    

    If you set the fourth parameter to -1, WideCharToMultiByte treats the input string as a null-terminated string. BSTRs are null-terminated for compatibility reasons, but you should never treat them as null-terminated because they can contain null characters as part of the string.