Что нового

Тип Boolean в структуре возвращается другим типом

Webarion

Осваивающий
Сообщения
143
Репутация
24
Ребят, такой вопрос. Почему тип Boolean возвращается как Int32? Хотел один байт писать, а получается, что 4. Или как-то по другому надо?

Код:
$tStruct = DllStructCreate('boolean var1')
DllStructSetData($tStruct, 'var1', True)

$vGet1 = DllStructGetData($tStruct, 'var1')
ConsoleWrite($vGet1 & ' (' & VarGetType($vGet1) & ')' & @CRLF)

$tStruct = 0

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

Вроде понял, что пишется правильно. Но тип всё равно возвращается Int32. Получается у DllStructGetData есть способ вернуть типы char int int64 double, а вот boolean почему-то не отдаёт
Код:
$tStruct = DllStructCreate('boolean var1')
DllStructSetData($tStruct, 'var1', True)

$vGet1 = DllStructGetData($tStruct, 'var1')
ConsoleWrite('Размер: ' & DllStructGetSize($tStruct) & @CRLF )
ConsoleWrite('Результат: ' & $vGet1 & ' (' & VarGetType($vGet1) & ')' & @CRLF)

$tStruct = 0

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

Пока решил так. Но открыт для хороших лаконичных вариантов.
Код:
$vGet1 = DllStructGetData($tStruct, 'var1') ? True : False
 
Последнее редактирование:

joiner

Модератор
Локальный модератор
Сообщения
3,557
Репутация
628
False - 0
True - 1
If значит -1 or 1 or.... > True
ElseIf значит ровно 0 .... > False

у меня ровно один байт
 

Вложения

  • Безымянный.jpg
    Безымянный.jpg
    53.3 КБ · Просмотры: 10
Последнее редактирование:
Автор
W

Webarion

Осваивающий
Сообщения
143
Репутация
24
False - 0
True - 1
If значит -1 or 1 or.... > True
ElseIf значит ровно 0 .... > False
Благодарю, я вроде понял логику разработчиков, хотя, на мой взгляд она не совсем логична. Но, это данность.
 
Последнее редактирование:

InnI

AutoIT Гуру
Сообщения
4,950
Репутация
1,444
Динамическое приведение типов в AutoIt иногда даёт неожиданный результат
Код:
$tStruct = DllStructCreate('byte var1')
DllStructSetData($tStruct, 'var1', 'A')
$vGet1 = DllStructGetData($tStruct, 'var1')
ConsoleWrite($vGet1 & ' (' & VarGetType($vGet1) & ') ' & DllStructGetSize($tStruct) & @CRLF)
$tStruct = 0

$tStruct = DllStructCreate('char var1')
DllStructSetData($tStruct, 'var1', 65)
$vGet1 = DllStructGetData($tStruct, 'var1')
ConsoleWrite($vGet1 & ' (' & VarGetType($vGet1) & ') ' & DllStructGetSize($tStruct) & @CRLF)
$tStruct = 0

$tStruct = DllStructCreate('char var1')
DllStructSetData($tStruct, 'var1', False)
$vGet1 = DllStructGetData($tStruct, 'var1')
ConsoleWrite($vGet1 & ' (' & VarGetType($vGet1) & ') ' & DllStructGetSize($tStruct) & @CRLF)
$tStruct = 0
 

xXx

╚{■_■}╗
Меценат
Сообщения
248
Репутация
95
даёт неожиданный результат
По моему результат ожидаемый если обратить внимание на "Примечания" к функциям *DllStructSetData()* и *DllStructGetData()*.
Код:
$tStruct = DllStructCreate('byte var1') ; Попробуйте 'byte var1[1]'
DllStructSetData($tStruct, 'var1', 'A') ; Нарушение условий функции => Ноль
$vGet1 = DllStructGetData($tStruct, 'var1')
ConsoleWrite($vGet1 & ' (' & VarGetType($vGet1) & ') ' & DllStructGetSize($tStruct) & @CRLF)
$tStruct = 0

$tStruct = DllStructCreate('char var1')
DllStructSetData($tStruct, 'var1', 65) ; Это число, которое будет воспринято как ASCII символ 0x41
$vGet1 = DllStructGetData($tStruct, 'var1') ; Chr(0x41)
ConsoleWrite($vGet1 & ' (' & VarGetType($vGet1) & ') ' & DllStructGetSize($tStruct) & @CRLF)
$tStruct = 0

$tStruct = DllStructCreate('char var1') ; Попробуйте 'char var1[5]'
DllStructSetData($tStruct, 'var1', False) ; Этот тип данных не строка и не число => данные будут преобразованы в строку
$vGet1 = DllStructGetData($tStruct, 'var1')
ConsoleWrite($vGet1 & ' (' & VarGetType($vGet1) & ') ' & DllStructGetSize($tStruct) & @CRLF)
$tStruct = 0
 

InnI

AutoIT Гуру
Сообщения
4,950
Репутация
1,444
Перечитал свою фразу и понял, что "неожиданный" нужно было указать в кавычках. Или поставить в конце подмигивающий смайлик.
Просто хотел показать на примерах, что для работы со структурами нужно хорошо разбираться в тонкостях приведения типов в AutoIt.
 
Автор
W

Webarion

Осваивающий
Сообщения
143
Репутация
24
Вот ещё очень интересное явление. В одном случае boolean записывается в память правильно, как 1 байт, в другом 4 байта, как int или тот же самый bool. Но, для такого типа это расточительно.

lYYy28jgrc.png

79tYNngkbL.png
 
Последнее редактирование:

xXx

╚{■_■}╗
Меценат
Сообщения
248
Репутация
95
Вот ещё очень интересное явление.
Это явление называется Не правильно *Выравненная Структура*.
В справке к DDL-функциям есть пару строк про это, но они не раскрывают всю важность выравнивания.
Код:
#include <WinAPIDiag.au3>

$sStruct = 'CHAR;int;BOOLEAN;BYTE' ; по идее 1+4+1+1 должно получиться 7
$tSTRUCT = DllStructCreate($sStruct)
$sSize = DllStructGetSize($tSTRUCT) ; ... а получается 12
_WinAPI_DisplayStruct($tSTRUCT, $sStruct, '[Size = ' & $sSize & ']')
$tSTRUCT = 0

$sStruct = 'CHAR;BOOLEAN;BYTE;align 1;int'; или 'CHAR;BOOLEAN;BYTE[2];int'
$tSTRUCT = DllStructCreate($sStruct)
$sSize = DllStructGetSize($tSTRUCT)
_WinAPI_DisplayStruct($tSTRUCT, $sStruct, '[Size = ' & $sSize & ']')
 
Последнее редактирование:

InnI

AutoIT Гуру
Сообщения
4,950
Репутация
1,444
А я вечно путаюсь в порядке байт при чтении byte и int
Код:
$t = DllStructCreate("byte[4]")
$p = DllStructGetPtr($t)
DllStructSetData($t, 1, 0x10203040)

$tB = DllStructCreate("byte[4]", $p)
ConsoleWrite(    DllStructGetData($tB, 1)  & @CRLF) ; 0x40302010
ConsoleWrite(Hex(DllStructGetData($tB, 1)) & @CRLF) ;   40302010

$tI = DllStructCreate("int", $p)
ConsoleWrite(    DllStructGetData($tI, 1)  & @CRLF) ; 270544960
ConsoleWrite(Hex(DllStructGetData($tI, 1)) & @CRLF) ;   10203040
Особенно напрягает при работе с массивом цветов пикселей - в зависимости от структуры получаешь ARGB или BGRA.
 
Автор
W

Webarion

Осваивающий
Сообщения
143
Репутация
24
Это явление называется Не правильно *Выравненная Структура*.
В справке к DDL-функциям есть пару строк про это, но они не раскрывают всю важность выравнивания.
Смотрел в эту сторону, правда не тестировал. Буду тестить.
Сообщение автоматически объединено:

А я вечно путаюсь в порядке байт при чтении byte и int
Код:
$t = DllStructCreate("byte[4]")
$p = DllStructGetPtr($t)
DllStructSetData($t, 1, 0x10203040)

$tB = DllStructCreate("byte[4]", $p)
ConsoleWrite(    DllStructGetData($tB, 1)  & @CRLF) ; 0x40302010
ConsoleWrite(Hex(DllStructGetData($tB, 1)) & @CRLF) ;   40302010

$tI = DllStructCreate("int", $p)
ConsoleWrite(    DllStructGetData($tI, 1)  & @CRLF) ; 270544960
ConsoleWrite(Hex(DllStructGetData($tI, 1)) & @CRLF) ;   10203040
Особенно напрягает при работе с массивом цветов пикселей - в зависимости от структуры получаешь ARGB или BGRA.
Меня эта инверсия самого раздражает. С цветам как раз сталкивался.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,673
Репутация
2,484
Прикольно, получается можно так конвертировать:
Код:
$nColor = 0xEF00AC
$iLen = 6

ConsoleWrite('Original:' & @TAB & '0x' & Hex($nColor, $iLen) & @CRLF)
ConsoleWrite('RGB2BGR:' & @TAB & _RGB2BGR($nColor, $iLen) & @CRLF)
ConsoleWrite('BGR2RGB:' & @TAB & _BGR2RGB($nColor, $iLen) & @CRLF & @CRLF)

$nColor = 0xAAEF00AC
$iLen = 8

ConsoleWrite('Original:' & @TAB & '0x' & Hex($nColor, $iLen) & @CRLF)
ConsoleWrite('RGB2BGR:' & @TAB & _RGB2BGR($nColor, $iLen) & @CRLF)
ConsoleWrite('BGR2RGB:' & @TAB & _BGR2RGB($nColor, $iLen) & @CRLF)

Func _RGB2BGR($nColor, $iLen = 6)
    Return '0x' & Hex(DllStructSetData(DllStructCreate('byte[' & ($iLen / 2) & ']'), 1, $nColor), $iLen)
EndFunc

Func _BGR2RGB($nColor, $iLen = 6)
    Return '0x' & Hex(DllStructSetData(DllStructCreate('int'), 1, $nColor), $iLen)
EndFunc
 
Верх