2009-11-22 1 views
8

동적으로 생성 된 메서드에서 내부 메서드를 호출하려고합니다. IL 코드는 간단합니다 : ldarg_0, callvirt, ret..NET의 동적 메서드에서 내부 메서드를 호출 할 수 있습니까?

메서드를 실행하면 TypeLoadException이 발생하여 내부 메서드가 정의 된 형식을로드 할 수 없다는 오류가 발생합니다.

동적 메서드 호스트 어셈블리가 메서드의 선언 형식 어셈블리의 친구가 아니기 때문에 논리적으로 보입니다.

그러나 Delegate.CreateDelegate가 작동하는 것처럼 동적 메서드가 여전히 작동 할 것으로 예상했습니다. 결국, 내부 메서드의 MethodInfo를 얻을 수 있었기 때문에 권한 허점이 뒤에 있습니다.

어쨌든 "동적으로 생성 된 내부 메서드를 호출 할 수 있습니까?"

감사합니다.

편집 :

: 나는 Data.String 인스턴스 속성에 액세스하는 방법은 두 개방형 인스턴스 대표를 생성 코드에서

using System; 
using System.Linq.Expressions; 
using System.Reflection; 
using System.Reflection.Emit; 

namespace A 
{ 
    internal class Data 
    { 
    internal string String { get; set; } 
    } 

    public static class Program 
    { 
    public static void Main() 
    { 
     Expression<Func<Data, string>> expr = x => x.String; 
     var getterInfo = ((PropertyInfo)((MemberExpression)expr.Body).Member).GetGetMethod(true); 
     var getter1 = (Func<Data, string>)Delegate.CreateDelegate(typeof(Func<Data, string>), getterInfo); 
     var dm = new DynamicMethod(string.Empty, typeof(object), new Type[] { typeof(object) }); 
     var gen = dm.GetILGenerator(); 
     gen.Emit(OpCodes.Ldarg_0); 
     gen.Emit(OpCodes.Castclass, typeof(Data)); 
     gen.Emit(OpCodes.Callvirt, getterInfo); 
     gen.Emit(OpCodes.Ret); 
     var getter2 = (Func<object, object>)dm.CreateDelegate(typeof(Func<object, object>)); 

     var data = new Data() { String = "Hello" }; 
     var str1 = getter1(data); 
     var str2 = getter2(data); 
    } 
    } 
} 

: 여기

문제를 보여주는 간단한 코드 샘플입니다

  • Delegate.CreateDelegate를 사용하는 안전한 getter1
  • 유형 uns AFE getter2 DynamicMethod

Delegate.CreateDelegate에 의해 생성 된 유형 안전 대리인이 작동을 사용하여, DynamicMethod 사용하는 사람은 TypeLoadException이 실패하면서.

getter가 작성되는 컨텍스트가 일반 적이기 때문에 유형에 안전한 접근 방식을 사용하지 않으려합니다. 물론이 문제를 해결할 수는 있지만 문제는 교장 문제입니다. 왜 Delegate.CreateDelegate가 성공할 때 DynamicMethod가 실패합니까?

+0

TypeLoadException은 어셈블리를 찾을 수 없음을 의미합니다. 퓨전 로그 뷰어의 내용은 무엇입니까? –

+0

융합 로그가 비어 있습니다. 어셈블리를로드 할 때 문제가 없어야합니다. 관련된 모든 어셈블리는 같은 폴더에 있습니다. – mark

+0

@JeremyMcGee가 맞습니다. 디버그 모드에서로드 된 어셈블리 목록을 AppDomain에서 가져 와서 대상 어셈블리를 확인합니다. 또한 코드를 여기에 넣어 확인하는 것이 좋습니다. –

답변

6

가시성 검사를 건너 뛰면 작동합니다.

변경

var dm = new DynamicMethod(string.Empty, typeof(object), new Type[] { typeof(object) }, true); 

msdn보기이 라인 : (. 특히 테이블의 모든 규칙)

이 생성자에 DOCO에서입니다.

restrictedSkipVisibility 유형이 제한와 동적 방법의 MSIL 액세스 유형 및 부재 에 JIT 가시성 검사를 건너 진정한 선택 System.Boolean : 그을 포함하는 어셈블리의 신뢰 레벨 형식 및 멤버가 동적 메서드를내는 호출 스택의 수준과 같거나 그보다 작아야합니다. 그렇지 않으면 false입니다.

+0

DynamicMethod가 .net 표준에 없으므로 .net 표준에서이를 수행 할 수있는 방법은 무엇입니까? – trampster