Что нового

При вызове СОМ-объекта возвращаемая строка обрывается на символе NUL

AvDA

Новичок
Сообщения
9
Репутация
0
Добрый день.
Есть библиотека, которая в определенный момент возвращает строку длинной 32 символа, в этой строке могут быть любые символы из таблицы ASCII, например самый первый (нулевой) символ NUL.
Проблема в том, что если в строке имеется симво NUL, то на этом строка и обрывается. Получается, что библиотека формирует строку правильно, а в момент "передачи" от библиотеке к AutoIt этот символ рассматривается как конец строки.
Подскажите, куда копать?

библиотека заведомо исправна, предназначена для работы с кассовыми аппаратами, устанавливается автоматически при установки вот этой программы ftp://ftp.shtrih-m.ru/download/FR/shtrih-fr-k/Drivers/DrvFR_A4.6.11.rar
 

madmasles

Модератор
Глобальный модератор
Сообщения
7,790
Репутация
2,322
AvDA,
А если как-то так?
Код:
Local $sStr, $sDelim, $iStart = 0, $iEnd = 255, $iStep = 1

For $j = 1 To 2
	For $i = $iStart To $iEnd Step $iStep
		$sStr &= Chr($i)
	Next
	$iStart = 255
	$iEnd = 0
	$iStep = -1
Next
ConsoleWrite('---' & @LF)
ConsoleWrite($sStr & @LF)
ConsoleWrite('---' & @LF)
$sDelim = _GetDelimiter($sStr)
ConsoleWrite($sDelim & @LF)
ConsoleWrite('---' & @LF)
$sStr = StringReplace($sStr, Chr(0), $sDelim)
ConsoleWrite('---' & @LF)
ConsoleWrite($sStr & @LF)

Func _GetDelimiter($s_String)
	Local $i_Count = 1, $s_Delim
	While 1
		$s_Delim = ''
		For $j = 1 To $i_Count
			$s_Delim &= Chr(Random(32, 255, 1));Chr(Random(1, 255, 1))
		Next
		If Not StringInStr($s_String, $s_Delim) Then Return $s_Delim
		$i_Count += 1
	WEnd
EndFunc   ;==>_GetDelimiter
Или так?
Код:
Local $sStr, $iStart = 0, $iEnd = 255, $iStep = 1

For $j = 1 To 2
	For $i = $iStart To $iEnd Step $iStep
		$sStr &= Chr($i)
	Next
	$iStart = 255
	$iEnd = 0
	$iStep = -1
Next
ConsoleWrite('---' & @LF)
ConsoleWrite($sStr & @LF)
ConsoleWrite('---' & @LF)
$sStr = StringReplace($sStr, Chr(0), '')
ConsoleWrite('---' & @LF)
ConsoleWrite($sStr & @LF)
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
AvDA
Если вывод в GUI то естественно все будет обрезано до Null. Как уже сказано выше удалить символы перед выводом для просмотра или заменить самим текстом [Null].





Добавлено:
Сообщение автоматически объединено:

madmasles
Вот более универсальный _GetDelimiter, вырезал из своей функции _StringSplitRegExp.
Код:
; Автор ..........: AZJIO
Func _GetDelimiter($sString)
	Local $sDelim, $, $Toggle, $iPos = 1
		For $i = 1 To 30
			$Toggle = Not $Toggle
			If $Toggle Then ; 1, 30, 3, 28    ...   27, 4, 29, 2
				$sDelim &= Chr($i)
			Else
				$sDelim &= Chr(32 - $i)
			EndIf
			$iPos = StringInStr($sString, $sDelim, 1, 1, $iPos) ; смещение позволяет найти разделитель за 1 проход
			If Not $iPos Then ExitLoop ; если вхождение не найдено, то разделитель сформирован
		Next
		If $iPos Then Return SetError(1, 0, $aError)
		Return $sDelim
EndFunc   ;==>_StringSplitRegExp
 
Автор
A

AvDA

Новичок
Сообщения
9
Репутация
0
Может я что-то недопонимаю, но, раз вот это работает правильно
Код:
$tmp=Chr(48)&Chr(49)&Chr(50)&Chr(0)&Chr(0)&Chr(48)&Chr(49)&Chr(50)&Chr(51)&Chr(50)&Chr(52)
MsgBox (0, "", Stringlen($tmp))

получим в MsgBox 11 ,
то и это должно работать правильно
Код:
$FR.Password=0
   $FR.DeviceCode=1
   $FR.DampRequest			; сформировали запрос
   $FR.GetData				; запросили первый блок,  данные первого блока в $FR.DataBlock
MsgBox(0,"",StringLen($FR.DataBlock)))

получим в MsgBox 5

т.е. получаем, что переменная $FR.DataBlock уже обрезана
хотя изначально она
14 06 11 29 46 00 00 00 62 08 71 23 77 00 00 00 50 40 30 00 FF FF FF FF FF FF FF FF FF FF FF FF
но в кодах ASCII
 

AZJIO

Меценат
Меценат
Сообщения
2,874
Репутация
1,194
AvDA
Да, объект обрезает, вот проверил на другом примере
Код:
$vNewValue = Chr(48) & Chr(49) & Chr(50) & Chr(0) & Chr(0) & Chr(48) & Chr(49) & Chr(50) & Chr(51) & Chr(50) & Chr(52)
Local $oDict = ObjCreate("Scripting.Dictionary")
$oDict.CompareMode = 0 ; бинарный режим
$oDict.Item(1) = $vNewValue
$sText = $oDict.Item(1)
MsgBox(0, Stringlen($sText), $sText)

Что делать не знаю, во внутрь AutoIt3 доступа нет, только сообщать о багах.
 
Верх