Jump to content

Recommended Posts

Posted

Hello,

I am receving data from a TcpServer. The data itself can be decoded by using a structure, for example:

$tStruct = DllStructCreate("char[12];int[13];byte[5];double[5]")

The length of the received data will match the length of the struct.

Is there an easy way to copy the binary data directly into the structure, so that I don't have to use BinaryMid etc.?

 

  • Solution
Posted (edited)
18 hours ago, HurleyShanabarger said:

Is there an easy way to copy the binary data directly into the structure, so that I don't have to use BinaryMid etc.?

If you read the data into a byte buffer struct, there's no need to copy it anywhere.  The data can be accessed by using an accessor struct that points to the memory location of the byte buffer struct.  If you must copy the data, then you can use _WinAPI_CopyStruct() to copy the byte buffer to another byte buffer and then access it using the same technique.

For example:

#include <WinAPIDiag.au3>

example()

Func example()
    Const $tagByteBuffer   = "byte byteBuffer[12];", _
          $tagAccessRecord = "int intVals[3]"

    Local $tByteBuffer   = DllStructCreate($tagByteBuffer), _
          $tAccessRecord = DllStructCreate($tagAccessRecord, DllStructGetPtr($tByteBuffer)); points to byte buffer

    Local $xData = Binary("0xFF000000FFFF0000FFFFFF00") ;3 little-endian ints


    ;Read data into byte buffer
    $tByteBuffer.byteBuffer = $xData

    ;Access & display values using the access record struct
    ConsoleWrite("$xData    = " & $xData & @CRLF & @CRLF)
    ConsoleWrite(StringFormat("intVal(1) = %8i (0x%08X)", $tAccessRecord.intVals(1), $tAccessRecord.intVals(1)) & @CRLF)
    ConsoleWrite(StringFormat("intVal(2) = %8i (0x%08X)", $tAccessRecord.intVals(2), $tAccessRecord.intVals(2)) & @CRLF)
    ConsoleWrite(StringFormat("intVal(3) = %8i (0x%08X)", $tAccessRecord.intVals(3), $tAccessRecord.intVals(3)) & @CRLF)

    ;Display byte buffer and access record struct
    _WinAPI_DisplayStruct($tByteBuffer  , $tagByteBuffer  , "Byte Buffer Struct")
    _WinAPI_DisplayStruct($tAccessRecord, $tagAccessRecord, "Access Record Struct")
EndFunc

Console output:

$xData    = 0xFF000000FFFF0000FFFFFF00

intVal(1) =      255 (0x000000FF)
intVal(2) =    65535 (0x0000FFFF)
intVal(3) = 16777215 (0x00FFFFFF)

 

Edited by TheXman
Posted

Thank you for the solution. I tried it myself using your way in the meantime, but it didn't work.

I started testing

DllCall("MSVCRT.DLL", "ptr:cdecl", "memcpy", "struct*", $tTrg, "struct*", $_lv_tSrc, "uint", DllStructGetSize($_lv_tSrc))

which was also doing the job, but I the other solution is better.

Also thank you for showing me 

_WinAPI_DisplayStruct

was not aware of that solution (acutally had my one version of it).

Posted

Functions already exist to do just that.
Download the UDF "BinaryHelpers.au3" from >>here<< and then you can solve your problem as follows:

#include "BinaryHelpers.au3"

Global $tagStruct = "char[12];int[13];byte[5];double[5]"
Global $bBin = Binary("0x68656C6C6F20776F726C640010270000204E000030750000409C000050C3000060EA00007011010080380100905F0100A0860100B0AD0100C0D40100D0FB0100BBCCDDEEFF000000000000000000F03F000000000000E03F555555555555D53F000000000000D03F9A9999999999C93F")

; convert the binary into a autoit dll-struct
Global $tStruct = _bin_BinToStruct($bBin, $tagStruct)

ConsoleWrite(DllStructGetData($tStruct, 1) & @CRLF)

 

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...