Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net PowerShell-如何进行反射。发出正确的IL操作码以调用[String]::加入DynamicMethod?_.net_Powershell_Reflection.emit - Fatal编程技术网

.net PowerShell-如何进行反射。发出正确的IL操作码以调用[String]::加入DynamicMethod?

.net PowerShell-如何进行反射。发出正确的IL操作码以调用[String]::加入DynamicMethod?,.net,powershell,reflection.emit,.net,Powershell,Reflection.emit,我一直在尝试使用PowerShell将CIL发送到DynamicMethod中,然后运行它,基本的操作也可以,所以我相信这种方法是可行的。我可以将int和string值推送到堆栈上并打印它们,这涉及到找到[console]::WriteLine([string])和[console]::WriteLine([int32])——即获取所有重载并按其参数类型进行过滤 现在我尝试调用[String]::Join(),但这是一个通用方法,需要键入才能加入[int32[]]数组。C#拆卸表明CIL说明如下

我一直在尝试使用PowerShell将CIL发送到DynamicMethod中,然后运行它,基本的操作也可以,所以我相信这种方法是可行的。我可以将int和string值推送到堆栈上并打印它们,这涉及到找到
[console]::WriteLine([string])
[console]::WriteLine([int32])
——即获取所有重载并按其参数类型进行过滤

现在我尝试调用
[String]::Join()
,但这是一个通用方法,需要键入才能加入
[int32[]]
数组。C#拆卸表明CIL说明如下:

IL_0018:  ldstr      ", "
IL_001d:  ldloc.2
IL_001e:  call       string [mscorlib]System.String::Join<int32>(string,
                               class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>)
IL_0023:  stloc.3
IL_0024:  ldloc.3
IL_0025:  call       void [mscorlib]System.Console::WriteLine(string)
它抛出:

Exception calling "Invoke" with "0" argument(s): "Operation could destabilize the runtime."
如果注释掉加载数组并调用Join的两行,那么代码运行良好,只需打印分隔符字符串
。所以这部分看起来还可以。我相当确定数组设置代码也可以,但不是绝对确定。它至少没有以错误的方式获取值和索引(这会引发索引越界异常)。我发出的操作码看起来像是在数组中存储值的C#反汇编


那么,发出String.Join调用的正确PowerShell代码是什么?正如在C#反汇编中看到的那样,它需要键入数组中的项
[int]
而不是整个数组
[int[]]
。更改我的PowerShell以删除额外的
[]
现在可以工作了:

$IL.EmitCall([opcodes]::Call, [string].GetDeclaredMethods('Join').where{
    $_.IsGenericMethod
}[0].MakeGenericMethod([int32]), $null)

我怎么找到的 我将DynamicMethod保存为
.exe
,然后在其上使用ILDasm将生成的代码与C版本进行比较

在我需要的地方:

string [mscorlib]System.String::Join<int32>(string,
                            class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>)
string[mscorlib]System.string::Join(string,
类[mscorlib]System.Collections.Generic.IEnumerable`1)
我得到了这个:

string [mscorlib]System.String::Join<int32[]>(string,
                            class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>)
string[mscorlib]System.string::Join(string,
类[mscorlib]System.Collections.Generic.IEnumerable`1)
特别是
Join
而不是
Join

string [mscorlib]System.String::Join<int32[]>(string,
                            class [mscorlib]System.Collections.Generic.IEnumerable`1<!!0>)