Что нового

IsBinary - функциями API

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Переношу один код с AutoIt на PureBasic чтобы сделать dll, в коде требуется проверка на бинарный код, а в PureBasic такой нативной функции нет, полазил на MSDN, тоже ни чего не нашёл, есть ли какие нибудь другие варианты для проверки или с помощью API?


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

Или так проверку сделать, если первых 2 байта = 0x то продолжаем, далее отделяем от бинарного кода 0x остаётся например 8FA43B далее считываем из скольки байт состоит строка (в данном случае из 6) потом делим на 2 и если получаемое число целое то возвращаем 1 а если нет(float) то возвращаем 0
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
а откуда берется этот бинарный код?
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
Viktor1703
в таком случае, там и так бинарный код. нет нужды для проверки.
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
"0x" не входит в бинарные данные, это только в строковом представлении присутствует. В PB вместо "0x" используется "$".
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Да я зная что в PB используется $, но я со скрипта в dll буду передавать в строковом виде - как есть, а дальше уже обрабатывать, или это не вариант для решения задачи?


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

в таком случае, там и так бинарный код. нет нужды для проверки

А если сбой случится и потеряется один байт или добавится, зачем же я буду функцию мучить и выводить не правильные данные?!


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

Переделал функцию для нормального бинарного вида

Код:
Procedure IsBinary(Binary)
  Len = StringByteLength(Str(Binary)) / 2
  If (Len * 2) = StringByteLength(Str(Binary))
    ProcedureReturn 1
  Else
     ProcedureReturn 0
  EndIf  
EndProcedure    

Debug IsBinary($DA63C7F5)
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
Viktor1703 сказал(а):
...но я со скрипта в dll буду передавать в строковом виде - как есть, а дальше уже обрабатывать, или это не вариант для решения задачи?

:blink:

Зачем? Помимо всего прочего, один байт в Unicode строке, например "0F" будет занимать 4 байта. Плюс геморой с преобразованием. В DLL нужно передавать именно двоичные данные, а точнее адрес на блок памяти, где они находятся - DllStructGetPtr().



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

Не путайте, двоичные данные в AutoIt, это не строка, а именно набор байт! "0x" - это просто следствие преобразования в строковый тип, например посредством ConsoleWrite().
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
Viktor1703 [?]
потеряется один байт или добавится
такого быть не может. могут прийти не все пакеты, но внутри пакета придет все.
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
А выше функция не подходит? бинарные данные же преабритают вид типа 123456, плюс ко всему PB не поддерживает Float и округляет число, допустим если мы передадим правильные данные то число после деления на 2 будет целым, и если это число умножить на 2 и сравнить с количеством символов и оно совпадёт то 1 а если после деления получается число 5.31235 то оно округлится до 5 и уже при умнажении на 2 на один байт будет меньше
 

kaster

Мой Аватар, он лучший самый
Команда форума
Глобальный модератор
Сообщения
4,020
Репутация
626
Viktor1703
данные, которые передаются по TCP уже бинарные. независимо что ты передал на входе - строку, целое число или дробь. то, что ты знаешь что конкретно было передано поможет полученные байты преобразовать обратно в нужный тип данных
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Ладно, понял, всем спасибо за разъяснения :smile:
 

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5,379
Репутация
2,724
PB поддерживает как float, так и double, и ничего никуда не округляет. Передавать в DLL данные можно примерно так:

Код:
$bData = TCPRecv(..., ..., 1)

$tData = DllStructCreate('byte[' & BinaryLen($bData) & ']')
DllStructSetData($tData, 1, $bData)
DllCall('MyLib.dll', 'int', 'MyFunc', 'ptr', DllStructGetPtr($tData))


В этом случае DLL должен выглядеть так:

Код:
ProcedureDLL.l MyFunc(*Binary)
	...
EndProcedure
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Yashied, хотел перенести в dll Ваш пример потоковой передачи изображения, но видно соображалки не хватит со структурами разобратся

Сервер:
Код:
#include <GUIConstantsEx.au3>
#include <Constants.au3>
#include <GDIPlus.au3>
#include <Memory.au3>
#include <WinAPIEx.au3>

Opt("TrayMenuMode", 3)

HotKeySet("^{F1}", "Camera")
HotKeySet("^{F2}", "Desktop")
HotKeySet("+{я}", "MaxQuality")
HotKeySet("+{ч}", "MinQuality")
HotKeySet("^{й}", "SpyExit")
HotKeySet("+{z}", "MaxQuality")
HotKeySet("+{x}", "MinQuality")
HotKeySet("^{q}", "Exit")

Global Const $STM_SETIMAGE = 0x0172
Global Const $STM_GETIMAGE = 0x0173
Global $hIndexQualiti
Global $hCommand
Global $hQuality = 20

TCPStartup()
$Main = TCPListen(_GetIP()z, 6093)
If @error Then
	Exit
EndIf

$Exit = TrayCreateItem("Выход")

$hForm = GUICreate("Remote Web Server v2.106.3.1", 320, 262, 0, 0, BitOR($WS_MINIMIZEBOX, $WS_CAPTION, $WS_POPUP, $WS_SYSMENU))
$Pic = GUICtrlCreatePic('', 0, 0, 320, 262)
GUICtrlSetState($Pic, $GUI_DISABLE)

$Menu = GUICtrlCreateMenu("&Устройство")
$hCamera = GUICtrlCreateMenuItem("Web Камера" & @TAB & "Ctrl+F1", $Menu)
$hDesktop = GUICtrlCreateMenuItem("Экран" & @TAB & "Ctrl+F2", $Menu)
$MenuQuality = GUICtrlCreateMenu("&Качество", -1, 1)
$hQualityMax = GUICtrlCreateMenuItem("Увеличить" & @TAB & "Shift+Z", $MenuQuality)
$hQualityMin = GUICtrlCreateMenuItem("Уменьшить" & @TAB & "Shift+X", $MenuQuality)

$ContextMenu = GUICtrlCreateContextMenu()
$bCamera = GUICtrlCreateMenuItem("Web Камера" & @TAB & "Ctrl+F1", $ContextMenu)
$bDesktop = GUICtrlCreateMenuItem("Экран" & @TAB & "Ctrl+F2", $ContextMenu)
GUICtrlCreateMenuItem("", $ContextMenu)
$bQualityMax = GUICtrlCreateMenuItem("Увеличить" & @TAB & "Shift+Z", $ContextMenu)
$bQualityMin = GUICtrlCreateMenuItem("Уменьшить" & @TAB & "Shift+X", $ContextMenu)
GUICtrlCreateMenuItem("", $ContextMenu)
$bExit = GUICtrlCreateMenuItem("Выход" & @TAB & "Ctrl+Q", $ContextMenu)

GUISetState()

Do
	$Socket = TCPAccept($Main)
	Switch TrayGetMsg()
		Case $Exit
			SpyExit()
	EndSwitch
	Switch GUIGetMsg()
		Case - 3, $bExit
			SpyExit()
	EndSwitch
Until $Socket <> -1

Camera()

Global $tHeader = DllStructCreate('byte[4]')
Global $pHeader = DllStructGetPtr($tHeader)
Global $bData = 0, $Count = 0

_GDIPlus_Startup()

While 1
	If Not IsBinary($bData) Then
		$bData = TCPRecv($Socket, 8384, 1)
		If @error Then
			Do
				$Socket = TCPAccept($Main)
				Switch TrayGetMsg()
					Case $Exit
						SpyExit()
				EndSwitch
				Switch GUIGetMsg()
					Case - 3, $bExit
						SpyExit()
				EndSwitch
			Until $Socket <> -1
		EndIf
	EndIf
	If IsBinary($bData) Then
		If Not $Count Then
			DllStructSetData($tHeader, 1, $bData)
			$tData = DllStructCreate('dword', $pHeader)
			$Size = DllStructGetData($tData, 1)
			$tData = DllStructCreate('byte[' & $Size & ']')
			$pData = DllStructGetPtr($tData)
		EndIf
		$Lenght = BinaryLen($bData)
		$Sum = $Count + $Lenght
		If $Sum > $Size Then
			$dL = $Size - $Count
			$tPart = DllStructCreate('byte[' & $dL & ']', $pData + $Count)
			DllStructSetData($tPart, 1, $bData)
			$tByte = DllStructCreate('byte[' & $Lenght & ']')
			$tRecv = DllStructCreate('byte[' & ($Lenght - $dL) & ']', DllStructGetPtr($tByte) + $dL)
			DllStructSetData($tByte, 1, $bData)
			$bData = DllStructGetData($tRecv, 1)
			$Sum = $Size
		Else
			$tPart = DllStructCreate('byte[' & $Lenght & ']', $pData + $Count)
			DllStructSetData($tPart, 1, $bData)
			$Count = $Sum
			$bData = 0
		EndIf
		If $Sum = $Size Then
			_SetScreenshot($Pic, $tData)
			$Count = 0
		EndIf
	EndIf
	
	Switch TrayGetMsg()
		Case $Exit
			SpyExit()
	EndSwitch
	Switch GUIGetMsg()
		Case - 3, $bExit
			SpyExit()
		Case $hCamera, $bCamera
			Camera()
		Case $hDesktop, $bDesktop
			Desktop()
		Case $hQualityMax, $bQualityMax
			MaxQuality()
		Case $hQualityMin, $bQualityMin
			MinQuality()
	EndSwitch
WEnd

Func Camera()
	$hCommand = "/Cam"
	TCPSend($Socket, "/Cam")
	WinMove($hForm, "", 0, 0, 320, 262)
EndFunc   ;==>Camera
Func Desktop()
	$hCommand = "/Des"
	TCPSend($Socket, "/Des")
	WinMove($hForm, "", 0, 0, @DesktopWidth, @DesktopHeight - 40)
EndFunc   ;==>Desktop
Func MaxQuality()
	$hQuality = ($hQuality + 10)
	If $hQuality >= 100 Then $hQuality = 100
	TCPSend($Socket, "/Oua" & $hQuality)
EndFunc   ;==>MaxQuality
Func MinQuality()
	$hQuality = ($hQuality - 10)
	If $hQuality <= 0 Then $hQuality = 0
	TCPSend($Socket, "/Oua" & $hQuality)
EndFunc   ;==>MinQuality

_GDIPlus_Shutdown()
TCPCloseSocket($Socket)
TCPShutdown()

Func _SetScreenshot($CtrlID, ByRef $tData, $fUpdate = 0)

	Local $hBitmap, $hPrev, $hScreen, $hMemory, $pMemory, $pStream, $pData, $iSize

	$hWnd = GUICtrlGetHandle($CtrlID)
	If Not $hWnd Then
		Return 0
	EndIf

	$pData = DllStructGetPtr($tData)
	$iSize = DllStructGetData(DllStructCreate('dword', $pData + 4), 1)
	$hMemory = _MemGlobalAlloc($iSize, $GMEM_MOVEABLE)
	$pMemory = _MemGlobalLock($hMemory)
	_MemMoveMemory($pData + 8, $pMemory, $iSize)
	_MemGlobalUnlock($hMemory)
	$pStream = _WinAPI_CreateStreamOnHGlobal($hMemory)
	$hBitmap = _GDIPlus_BitmapCreateFromStream($pStream)
	$hScreen = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
	_GDIPlus_BitmapDispose($hBitmap)
	_MemGlobalFree($hMemory)
	_WinAPI_DeleteObject(_SendMessage($hWnd, $STM_SETIMAGE, $IMAGE_BITMAP, $hScreen))
	$hPrev = _SendMessage($hWnd, $STM_GETIMAGE)
	If $hPrev <> $hScreen Then
		_WinAPI_DeleteObject($hScreen)
	EndIf
	If $fUpdate Then
		_WinAPI_UpdateWindow($hWnd)
	EndIf
	Return 1
EndFunc   ;==>_SetScreenshot

Func _GDIPlus_BitmapCreateFromStream($pStream)
	Local $Ret = DllCall($ghGDIPDll, 'uint', 'GdipCreateBitmapFromStream', 'ptr', $pStream, 'ptr*', 0)
	If (@error) Or ($Ret[0]) Then
		Return SetError(@error, @extended, 0)
	EndIf
	Return $Ret[2]
EndFunc   ;==>_GDIPlus_BitmapCreateFromStream

Func Exit()
	Exit
EndFunc   ;==>Exit
 
Верх