0

私は以下を放出しようとしています:

これは、動的に発行されるクラスのプロパティとして含まれる構造体です。

public struct GeoPoint
{
    public double? lat { get; set; }

    public double? lon { get; set; }
}

私は次のクラスを放出する必要があります:

public class GeoPointOwner
{
    public GeoPoint GeoPoint{get; set;}
    public double? Getlat ()
    {
        return GeoPoint.lat;
    }
}

メソッドGeoPointOwner.Getlatを適切に発行する方法がわかりません

これが私のコードです:

var mbGet = typeBuilder.DefineMethod("Getlat", MethodAttributes.Public, typeof(double?), Type.EmptyTypes);
var genGet = mbGet.GetILGenerator();
genGet.Emit(OpCodes.Ldarg_0);
//getMethodInfo below is MethodInfo of Getter of GeoPoint property
genGet.Emit(OpCodes.Call, getMethodInfo);
var getMethod = typeof(GeoPoint).GetProperty("lat").GetGetMethod(true);
//code emitted below fails when invoked
genGet.Emit(OpCodes.Callvirt, getMethod);
genGet.Emit(OpCodes.Stloc_0);
genGet.Emit(OpCodes.Ret);
4

1 に答える 1

2

コメントで提案したように、このようなエラーがある場合は、生成されたアセンブリで PEVerify を使用することをお勧めします。コードでそれを使用すると、修正に役立ちます。

生成されたアセンブリで実行すると、次のエラーが発生します。

[GeoPointOwner::Getlat][offset 0x00000006] 値型メソッドの Callvirt。

callvirtを使用して値型のメソッドを呼び出すことはできません(この場合、それは のゲッターですGeoPoint.lat) call。代わりに使用してください。

それを修正した後、2 つの新しいエラーが発生します。

[GeoPointOwner::Getlat][オフセット 0x00000006][見つかった値 'ConsoleApplication1.GeoPoint'][値 'ConsoleApplication1.GeoPoint' の予想されるアドレス] スタック上の予期しない型です。

[GeoPointOwner::Getlat][offset 0x0000000B] 認識されないローカル変数番号です。

最初に2番目のものを修正します。stloc_0スタックの一番上にある値をローカル変数 #0 に格納するを使用しています。ローカルを宣言していないため、失敗します。ここには地元の人は必要ないのに、なぜそんなことをするのか理解できません。の結果を直接返すことがcallできるので、 を削除できますstloc_0

最初のエラーはより複雑です。値型でメソッドを呼び出す場合、実際にはその型の変数への参照が必要です。現在、変数はありません。つまり、変数を作成し ( を使用DeclareLocal())、値をローカルに保存し ( stloc)、そのローカルのアドレスをロードする ( ldloca) 必要があります。詳細については、構造体でのメソッド呼び出し?の質問を参照してください。.

これらの変更により、コードは次のようになります。

var getlatBuilder = type.DefineMethod("Getlat", MethodAttributes.Public, typeof(double?), Type.EmptyTypes);
var il = getlatBuilder.GetILGenerator();
var getPointLocal = il.DeclareLocal(typeof(GeoPoint));

il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Call, geoPointGetter);

il.Emit(OpCodes.Stloc, getPointLocal);
il.Emit(OpCodes.Ldloca, getPointLocal);

var latGetter = typeof(GeoPoint).GetProperty("lat").GetGetMethod(true);
il.Emit(OpCodes.Call, latGetter);
il.Emit(OpCodes.Ret);
于 2013-01-31T16:58:41.967 に答える