将字节数组分配给 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]
- 最后一次调用失败,
$MyObject
是$null
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[]])
正在寻找将字节数组分配给对象的方法 - 尝试使用 -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]
- 最后一次调用失败,
$MyObject
是$null
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[]])