3

問題があります。これは私のコードです:

var method = new DynamicMethod("dummy", null, Type.EmptyTypes);
var g = method.GetILGenerator();
g.DeclareLocal(typeof(int));

Label inequality = g.DefineLabel();
Label equality = g.DefineLabel();
Label end = g.DefineLabel();

g.Emit(OpCodes.Ldstr, "string");
g.Emit(OpCodes.Ldstr, "string");
g.Emit(OpCodes.Call, typeof(String).GetMethod("op_Equality", new Type[]{typeof(string), typeof(string)}));
g.Emit(OpCodes.Stloc_0);
g.Emit(OpCodes.Ldloc_0);
g.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[]{typeof(int)}));
g.Emit(OpCodes.Ldloc_0);
g.Emit(OpCodes.Ldc_I4_1);
g.Emit(OpCodes.Ceq);
g.Emit(OpCodes.Brtrue_S, equality);
g.Emit(OpCodes.Brfalse_S, inequality);
g.MarkLabel(inequality);
g.Emit(OpCodes.Ldstr, "Specified strings are different.");
g.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[]{typeof(string)}));
g.Emit(OpCodes.Br_S, end);
g.MarkLabel(equality);
g.Emit(OpCodes.Ldstr, "Specified strings are same.");
g.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));
g.Emit(OpCodes.Br_S, end);
g.MarkLabel(end);
g.Emit(OpCodes.Ret);

var action = (Action)method.CreateDelegate(typeof(Action));
action();

これが私の結果です:

1
Specified strings are different.

しかし、なぜ出力が間違っているのですか?Ceq命令は、op_Equationの結果として1と、スタックの最上位にある0を比較しています。そして、1は0に等しくありません。それでは、なぜそうなのですか?エラーはどこにありますか?私を助けてください。

4

2 に答える 2

5

その後g.Emit(OpCodes.Brtrue_S, inequality);、手動で「equality」ステートメントにジャンプする必要があります。それ以外の場合は、とにかく次の命令を実行します。したがって、その後に次の行を挿入する必要があります。

g.Emit(OpCodes.Br_S, equality);

equalityまた、とにかく次の命令として宣言されたときにラベルにジャンプすることは意味がありません。だからそれを削除します。

したがって、セクションは次のようになります。

g.Emit(OpCodes.Ceq);

g.Emit(OpCodes.Brtrue_S, inequality); // if true goto inequality
g.Emit(OpCodes.Br_S, equality); // else goto equality

g.MarkLabel(inequality);            
g.Emit(OpCodes.Ldstr, "Specified strings are different.");
g.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[]{typeof(string)}));
g.Emit(OpCodes.Br_S, end); // goto end

g.MarkLabel(equality);
g.Emit(OpCodes.Ldstr, "Specified strings are same.");
g.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));

g.MarkLabel(end);
g.Emit(OpCodes.Ret);
于 2012-06-21T14:25:47.033 に答える
4

あなたのブランチは、とにかくステートメントの直後にあるラベル「不等式」にあります。したがって、分岐するかどうかに関係なく、これが呼び出されるコードです。「equality」というラベルに分岐する必要があります。

また、あなたの行g.Emit(OpCodes.Brfalse_S, equality);は決して到達されないので無意味です-あなたは前のステートメントでそれを飛び越えます。また、ロジックが修正されると、「不等式」ラベルは実際にはどこにも使用されないため、それを破棄することもできます。

于 2012-06-21T14:18:15.817 に答える