C++ OPOS BSTR*未正确转换

C++ OPOS BSTR*未正确转换,c++,bstr,opos,C++,Bstr,Opos,因此,经过一系列研究后,我发现使用WideChartMultiByte可以通过OPOS将数据从控制对象发送到我的自定义So。我们遇到了一个bug。在DirectIO部分,C#控制对象的映射是DirectIO(int命令、ref int数据、ref string对象) 在最长的时间里,我们只需要通过DirectIO发送简单的命令。例如,要打开LED,我们将数据设置为以千秒为单位的长度,将对象设置为颜色。当我们需要将数据写入标签或卡片时,文本必须从一个特殊的XML样式字符串解析为一个字节数组。。。现

因此,经过一系列研究后,我发现使用WideChartMultiByte可以通过OPOS将数据从控制对象发送到我的自定义So。我们遇到了一个bug。在DirectIO部分,C#控制对象的映射是DirectIO(int命令、ref int数据、ref string对象)

在最长的时间里,我们只需要通过DirectIO发送简单的命令。例如,要打开LED,我们将数据设置为以千秒为单位的长度,将对象设置为颜色。当我们需要将数据写入标签或卡片时,文本必须从一个特殊的XML样式字符串解析为一个字节数组。。。现在我们需要一个字节数组,使用ASCII编码将该数组转换成字符串形式,并将其写入

问题是,当我在服务对象中转换这个字符串时,它没有正确地转换它。即使SysStringLen知道长度是4bytes,它似乎在null时停止。示例控件对象执行此操作

        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);
所以他看到了这一点

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);
产出

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


基本上,只要到达第一个空字符,其余的数据就会丢失。现在,如果我把数字从一个字符串转换成一个字符串,结果是可以的,因为我有一个ByteUtil函数,只用于那个场合。。。但对我来说,这样做似乎不太合适。。。为什么不能将其作为字节数组?

非常简单,只需更改此行:

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


如果将第四个参数设置为-1,则WideCharToMultiByte会将输入字符串视为以null结尾的字符串。出于兼容性原因,BSTR以null结尾,但您不应将其视为以null结尾,因为它们可以包含null字符作为字符串的一部分。

我想我可能只是回答了我自己的问题,我们编写的另一种卡也会发送一个表示字节数组的字符串并将其转换。。。所以我们应该坚持这种方法。。。这符合OPOS的标准。。。但是如果有人有什么建议,请随时告诉我:)哇,谢谢你给我打电话:)哈哈哈,那么在这张纸条上,如果值是字符串,我应该以null结尾,还是WideChartMultiByte为我做这件事?我之所以这么问,是因为我不想要一个5字节的数组,而实际上它是一个4字节数组。。但是很明显,对于一个字符串,我需要以null结尾,对吗?这在WideChartMultiByte的MSDN文档中有解释。如果将-1作为cchWideChar参数传递(这当然意味着需要传递以null结尾的输入字符串),或者如果输入字符串在作为cchWideChar传递的长度内包含null字符,则输出字符串将以null结尾。无论如何,在这种情况下,null终止它没有多大意义,因为字符串中有null字符。此外,以null结尾的字符串通常是不好的,您应该使用长度前缀字符串(如BSTR)或字符串类(如std::string、CString等)
WideCharToMultiByte(CP_ACP, 0, *pString, len, dataObject, len, NULL, NULL);