Что нового

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

Viktor1703

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


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

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

kaster

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

Viktor1703

AutoIT Гуру
Сообщения
1 535
Репутация
411
Приходит по TCP
 

kaster

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

Yashied

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

Viktor1703

AutoIT Гуру
Сообщения
1 535
Репутация
411
Да я зная что в 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 713
Viktor1703 сказал(а):
...но я со скрипта в dll буду передавать в строковом виде - как есть, а дальше уже обрабатывать, или это не вариант для решения задачи?
:blink:

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



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

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

kaster

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

Viktor1703

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

kaster

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

Viktor1703

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

Yashied

Модератор
Команда форума
Глобальный модератор
Сообщения
5 379
Репутация
2 713
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
 
Автор
Viktor1703

Viktor1703

AutoIT Гуру
Сообщения
1 535
Репутация
411
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
 
Верх