2013-02-10 3 views
0

Итак, после нескольких исследований я обнаружил, что использование WideCharToMultiByte отлично подойдет для отправки данных из объекта управления через OPOS в мой пользовательский SO. хорошо мы столкнулись с ошибкой. В части DirectIO карта C# Control Object представляет собой DirectIO (int command, ref int data, ref string object);OPOS BSTR * неправильно преобразован

и в течение самого длительного времени нам просто нужно было отправлять простые команды через DirectIO. Например, чтобы включить светодиод, мы установили бы данные как длину в миллисекундах, а объект - цвет. Когда нам нужно было записывать данные в тег или карту, текст должен был анализироваться из специальной строки в стиле XML в байтовый массив ... ну, теперь возникла необходимость в том, что нам нужно иметь массив байтов, использовать кодировку ASCII поместить этот массив в строчную форму и записать его.

Проблема в том, что когда я конвертирую эту строку в свой служебный объект, она не преобразует ее правильно. он, кажется, останавливается на нуле, хотя SysStringLen знает, что длина составляет 4 байта. Пример Объект управления делает это

 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 только для этого случая ... но мне кажется, что мне не нужно это делать ... почему не удается Я просто использую его как массив BYTE?

+0

Я думаю, что, может быть, я просто ответил на свой вопрос, что у другого типа карты, которую мы пишем, мы отправляем строку, представляющую массив байтов, и преобразуем ее ... поэтому мы должны просто придерживаться этого метода ... и что соответствует стандартам OPOS ... но если у кого-то есть предложение, пожалуйста, не стесняйтесь говорить мне :) –

ответ

2

Очень легко, просто изменить эту строку:

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

в:

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

Если установить четвертый параметр -1, WideCharToMultiByte обрабатывает входную строку в виде строки с завершающим нулем. BSTR заканчиваются нулями по соображениям совместимости, но вы никогда не должны рассматривать их как завершающие нуль, поскольку они могут содержать нулевые символы как часть строки.

+0

wow, спасибо за pwning me :) hahaha так на этой заметке, тогда, если значение - это строка, я должен закончить ее нулевой или широкоформатный, это для меня? Я спрашиваю, потому что я не хочу иметь массив 5byte, когда он действительно представляет собой 4 байтовый массив. Но, очевидно, для строки мне нужно, чтобы конец null был прав? –

+1

Это описано в документации MSDN для WideCharToMultiByte. Выходная строка будет завершаться нулем, если вы передадите -1 в качестве параметра cchWideChar (что, конечно, означает, что вам нужно передать входную строку с нулевым завершением), или если входная строка содержит нулевой символ в пределах длины, которую вы передаете как cchWideChar. В любом случае, в этом случае не имеет смысла обнулить нуль, поскольку в строке есть нулевые символы. Кроме того, строки с нулевым завершением в общем случае плохие, вы должны использовать строки с префиксом длины, такие как BSTR, или строковые классы, такие как std :: string, CString и т. Д. – user1610015