将字节数组分配给 PowerShell 中的对象

Assigning byte array to an object in PowerShell

正在寻找将字节数组分配给对象的方法 - 尝试使用 -as 运算符但没有成功。 (针对 PowerShell 版本 5.1)

$CSharpCode = @"
using System;
namespace TestStructure
{
    public struct TestStructure3
    {
       public Byte Field1;
       public Byte Field2;
       public UInt32 Field3;
       public UInt32 Field4;
    }

    public struct TestStructure2
    {
       public UInt32 Field1;
       public UInt32 Field2;
    }

    public struct TestStructure1
    {
       public UInt16 Field1;
       public UInt16 Field2;
       public TestStructure2 Field3;
       public TestStructure3 Field4;
    }
}
"@

Add-Type -TypeDefinition $CSharpCode

[byte[]]$BytesArray = 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22

$MyObject = $BytesArray -as [TestStructure.TestStructure1]

PowerShell 本身不会在字节数组和 blittable 类型的初始化实例之间进行转换,但您可以编写一个小的实用函数来处理它,如下所示:

function ConvertTo-Struct
{
  # Only accept struct types (sealed value types that are neither primitive nor enum)
  param(
    [Parameter(Mandatory = $true)]
    [ValidateScript({ $_.IsValueType -and $_.IsSealed -and -not($_.IsPrimitive -or $_.IsEnum) })]
    [Type]$TargetType,

    [Parameter(Mandatory = $true)]
    [byte[]]$BinaryData
  )

  # Start by calculating minimum size of the underlying memory allocation for the new struct
  $memSize = [System.Runtime.InteropServices.Marshal]::SizeOf([type]$TargetType)

  # Make sure user actually passed enough data to initialize struct
  if($memSize -gt $BinaryData.Length){
    Write-Error "Not enough binary data to create an instance of [$($TargetType.FullName)]"
    return
  }

  # now we just need some unmanaged memory in which to create our struct instance
  $memPtr = [IntPtr]::Zero
  try {
    $memPtr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($memSize)

    # copy byte array to allocated unmanaged memory from previous step
    [System.Runtime.InteropServices.Marshal]::Copy($BinaryData, 0, $memPtr, $memSize)

    # then marshal the new memory region as a struct and return
    return [System.Runtime.InteropServices.Marshal]::PtrToStructure($memPtr, [type]$TargetType)
  }
  finally {
    # and finally remember to clean up the allocated memory
    if($memPtr -ne [IntPtr]::Zero){
      [System.Runtime.InteropServices.Marshal]::FreeHGlobal($memPtr)
    }
  }
}

现在我们已经把它摆正了,让我们开始使用它吧:

$testStructure1 = ConvertTo-Struct -TargetType ([TestStructure.TestStructure1]) -BinaryData (1..24 -as [byte[]])