7

System.Reflection.Emit 名前空間を使用しintて配列を作成するための IL 機関をいくつか書いています。double

int配列を作成するために、次のコードを使用しています。

LocalBuilder arr = gen.DeclareLocal(typeof(int));
gen.Emit(OpCodes.Ldc_I4_1);
gen.Emit(OpCodes.Newarr, typeof(int));
gen.Emit(OpCodes.Stloc, arr);
gen.Emit(OpCodes.Ldloc, arr);
gen.Emit(OpCodes.Ldc_I4_0);
gen.Emit(OpCodes.Ldc_I4, 500);
gen.Emit(OpCodes.Stelem_I4);

gen.Emit(OpCodes.Ldloc, arr);
gen.Emit(OpCodes.Ldc_I4_0);
gen.Emit(OpCodes.Ldelem_I4);
gen.Emit(OpCodes.Call,typeof(Console).GetMethod("WriteLine",new Type[]{typeof(int)}));

期待どおりに動作しており、コンソールに 500 が出力されます。

double以下に示すように、配列を作成しようとしたのと同じ方法です。

LocalBuilder arr = gen.DeclareLocal(typeof(double));
gen.Emit(OpCodes.Ldc_I4_1);
gen.Emit(OpCodes.Newarr, typeof(double));
gen.Emit(OpCodes.Stloc, arr);
gen.Emit(OpCodes.Ldloc, arr);
gen.Emit(OpCodes.Ldc_I4_0);
gen.Emit(OpCodes.Ldc_R8, 500D);
gen.Emit(OpCodes.Stelem_R8);

gen.Emit(OpCodes.Ldloc, arr);
gen.Emit(OpCodes.Ldc_I4_0);
gen.Emit(OpCodes.Ldelem_I8);
gen.Emit(OpCodes.Call,typeof(Console).GetMethod("WriteLine",new Type[]{typeof(double)}));

残念ながら、これは機能せず、pereviewそれを使用して生成されたアセンブリを検査すると、次のエラーが発生しました。

Microsoft (R) .NET Framework PE Verifier.  Version  4.0.30319.1
Copyright (c) Microsoft Corporation.  All rights reserved.

[IL]: Error: [C:\temp\Research\Research\bin\Debug\MyMod.exe : Foo::Main][offset 0x00000006][found ref array md
array 'System.Double[]'][expected Double] Unexpected type on the stack.
[IL]: Error: [C:\temp\Research\Research\bin\Debug\MyMod.exe : Foo::Main][offset 0x00000012] Expected single di
mension array.
2 Error(s) Verifying MyMod.exe

さらに、生成されたアセンブリを次を使用して検査しましたildasm

.method privatescope static void  Main$PST06000001() cil managed
{
  .entrypoint
  // Code size       28 (0x1c)
  .maxstack  3
  .locals init (float64 V_0)
  IL_0000:  ldc.i4.1
  IL_0001:  newarr     [mscorlib]System.Double
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  ldc.i4.0
  IL_0009:  ldc.r8     500.
  IL_0012:  stelem.r8
  IL_0013:  ldloc.0
  IL_0014:  ldc.i4.0
  IL_0015:  ldelem.i8
  IL_0016:  call       void [mscorlib]System.Console::WriteLine(float64)
  IL_001b:  ret
} // end of method Foo::Main

何か考えはありますか?

4

1 に答える 1

7
LocalBuilder arr = gen.DeclareLocal(typeof(int));
gen.Emit(OpCodes.Ldc_I4_1);
gen.Emit(OpCodes.Newarr, typeof(int));
gen.Emit(OpCodes.Stloc, arr);

arrがタイプではないのはなぜint[]ですか?

私は、peverify が両方のバージョンで文句を言うと確信しています。

それが最初のバージョンで動作するという事実は、単に「運」です*。

*理由はもっと複雑です。

于 2011-06-08T07:21:55.027 に答える