Что нового

Создание структуры

musicstashall

Знающий
Сообщения
322
Репутация
7
Всем доброго, новогоднего.

Читаю бинарную строку из реестра, получаю из нее структуру. Далее получаю из структуры массив. Заполняю массив, конвертирую массив в структуру, затем структуру — в бинарную строку и обратно в реестр. Проблема появилась на x64, числа уже не те. В частности, при запуске на x64, при чтении структуры, в последних ячейках, получаю совсем не те значения. Прошу подправить. Может функи какие полезные подскажете.
Требования к структуре: Первые восемь значений Key1 ... Key8 — это четырехзначные целые числа, далее, до конца — однозначные целые числа.
Изначально, в бинарной строке следующий ряд чисел:
2651
416
0
0
0
0
0
0
1
1
2
8
8
8
8

Код:
#include <Array.au3>


Global $Binary = '0x5B0A0000A001000000000000000000000000000000000000000000000000000001000000010000000200000008000000080000000800000008000000'
Global Const $tagHotKey = 'Int Key1;Int Key2;Int Key3;Int Key4;Int Key5;Int Key6;Int Key7;Int Key8;Int Mous1;Int Mous2;Int Mous3;Int Func1;Int Func2;Int Func3;Int Func4'

Global $tHotKey = _BinaryToStructure($Binary, $tagHotKey)
Global $aStruct = _StructureToArray($tHotKey)
_WinAPI_DisplayStruct($tHotKey, $tagHotKey)
_ArrayDisplay($aStruct, 'Полученный массив из структуры')

$aStruct[3] = 2651
$aStruct[4] = 416
$aStruct[5] = 2651
$aStruct[6] = 416
$aStruct[7] = 2651
$aStruct[8] = 416

_ArrayDisplay($aStruct, 'Измененный массив')
_ArrayToStructure($tHotKey, $aStruct)
$Binary = _StructureToBinary($tHotKey, $tagHotKey)
ConsoleWrite($Binary&@CR)
MsgBox('','', $Binary)
$tHotKey = _BinaryToStructure($Binary, $tagHotKey)
_WinAPI_DisplayStruct($tHotKey, $tagHotKey)
_ArrayDisplay(_StructureToArray($tHotKey), 'Вновь полученный массив из структуры')

Func _BinaryToStructure($Binary, $tagSTRUCTURE)
	Local $byte = StringLen($Binary)-2
	If @AutoItX64 Then $byte += 2
	Local $tSTR = DllStructCreate('byte [' & $byte & ']')
	Local $tuSTRUCT = DllStructCreate($tagSTRUCTURE, DLLStructGetPtr($tSTR, 1))
	DllStructSetData($tSTR, 1, $Binary)
	Return $tuSTRUCT
 EndFunc

Func _StructureToBinary($structure, $tagSTRUCTURE)
	Local $byte = DllStructGetSize($structure)
	Local $tBYTE = DllStructCreate('byte [' & $byte & ']')
	Local $tSTRUCT = DllStructCreate($tagSTRUCTURE, DLLStructGetPtr($tBYTE, 1))
	Local $i = 0
	While 1
		$i += 1
		DllStructSetData($tSTRUCT, $i, DllStructGetData($structure, $i))
		If @error Then Return DllStructGetData($tBYTE, 1)
	WEnd
EndFunc

Func _StructureToArray($tSTRUCT)
	Local $data[1], $value, $i = 0
	While 1
		$i += 1
		$value = DllStructGetData($tSTRUCT, $i)
		If @error Then Return $data
		_ArrayAdd($data, $value)
		$data[0] = $i
	Wend
	Return $data
EndFunc

Func _ArrayToStructure($tSTRUCT, $Array)
	If Not IsDllStruct($tSTRUCT) Then Return SetError(1)
	For $i = 1 To $Array[0]
		DllStructSetData($tSTRUCT, $i, $Array[$i])
	Next
EndFunc
 
Автор
M

musicstashall

Знающий
Сообщения
322
Репутация
7
Нашел ошибку сам. Изменил размер создаваемой структуры, «-2» убрал. Наугад. Каким образом и что там получается, не понимаю. Как тогда размер определять?

Код:
Func _BinaryToStructure($Binary, $tagSTRUCTURE)
	Local $byte = StringLen($Binary)
	Local $tSTR = DllStructCreate('byte [' & $byte & ']')
	Local $tuSTRUCT = DllStructCreate($tagSTRUCTURE, DLLStructGetPtr($tSTR, 1))
	If @error Then MsgBox('','', 'error = '&@error)
	DllStructSetData($tSTR, 1, $Binary)
	Return $tuSTRUCT
 EndFunc
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
раз бинарные, то
Код:
Local $byte = BinaryLen($Binary)
 
Автор
M

musicstashall

Знающий
Сообщения
322
Репутация
7
Получается в два раза меньше. От чего бежали... Все-таки не работает у меня эта структура. Добавил просмотр структуры для контроля
Код:
_WinAPI_DisplayStruct($tHotKey, $tagHotKey)


Сейчас заметил, что DisplayStruct всегда разные значения показывает. Это функция неисправная?? Или мои преобразования кривые?


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

С каждым запуском всегда разные значения, как будто я запускаю генератор случайных чисел)) как такое вообще может быть?? Я устал бороться с волшебствами))


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

Сделал следующим образом. Все этапы проходят четко, все числа соответствуют, но в последнем, где структура переписывается в массив, получаю многозначные числа. Как это понимать? Только что в структуре были нормальные числа, получили значения, а они уже другие.

Код:
#include <Array.au3>
#include <WinAPIDiag.au3>

Global $Binary = '0x5B0A0000A001000000000000000000000000000000000000000000000000000001000000010000000200000008000000080000000800000008000000'
Global Const $tagHotKey = 'Int Key1;Int Key2;Int Key3;Int Key4;Int Key5;Int Key6;Int Key7;Int Key8;Int Mous1;Int Mous2;Int Mous3;Int Func1;Int Func2;Int Func3;Int Func4'

Global $tHotKey = _BinaryToStructure($Binary, $tagHotKey)
Global $aStruct = _StructureToArray($tHotKey)
_WinAPI_DisplayStruct($tHotKey, $tagHotKey, 'Структура из строки')
_ArrayDisplay($aStruct, 'Полученный массив из структуры')

$aStruct[3] = 2651
$aStruct[4] = 416
$aStruct[5] = 2651
$aStruct[6] = 416
$aStruct[7] = 2651
$aStruct[8] = 416

_ArrayDisplay($aStruct, 'Измененный массив')
_ArrayToStructure($tHotKey, $aStruct)
$Binary = _StructureToBinary($tHotKey, $tagHotKey)
ConsoleWrite($Binary&@CR)
MsgBox('','Новая строка', $Binary)
$tHotKey = _BinaryToStructure($Binary, $tagHotKey)
_WinAPI_DisplayStruct($tHotKey, $tagHotKey,'Новая структура из строки')
$aStruct = _StructureToArray($tHotKey)
_ArrayDisplay($aStruct, 'Вновь полученный массив из структуры')

Func _BinaryToStructure($Binary, $tagSTRUCTURE)
	Local $byte = BinaryLen($Binary)*2
	If @AutoItX64 Then $byte *=2
	Local $tSTR = DllStructCreate('byte [' & $byte & ']')
	Local $tuSTRUCT = DllStructCreate($tagSTRUCTURE, DLLStructGetPtr($tSTR, 1))
	If @error Then MsgBox('','', 'error = '&@error)
	DllStructSetData($tSTR, 1, $Binary)
	Return $tuSTRUCT
 EndFunc

Func _StructureToBinary($structure, $tagSTRUCTURE)
	Local $byte = DllStructGetSize($structure)
	Local $tBYTE = DllStructCreate('byte [' & $byte & ']')
	Local $tSTRUCT = DllStructCreate($tagSTRUCTURE, DLLStructGetPtr($tBYTE, 1))
	Local $i = 0
	While 1
		$i += 1
		DllStructSetData($tSTRUCT, $i, DllStructGetData($structure, $i))
		If @error Then Return DllStructGetData($tBYTE, 1)
	WEnd
EndFunc

Func _StructureToArray($tSTRUCT)
	Local $data[1], $value, $i = 0
	While 1
		$i += 1
		$value = DllStructGetData($tSTRUCT, $i)
		If @error Then Return $data
		_ArrayAdd($data, $value)
		$data[0] = $i
	Wend
	Return $data
EndFunc

Func _ArrayToStructure(ByRef $tSTRUCT, $Array)
	If Not IsDllStruct($tSTRUCT) Then Return SetError(1)
	For $i = 1 To $Array[0]
		DllStructSetData($tSTRUCT, $i, $Array[$i])
	Next
EndFunc
 
Автор
M

musicstashall

Знающий
Сообщения
322
Репутация
7
Всё выяснилось, функция _WinAPI_DisplayStruct неисправна, она ломает структуру.
 
Верх