2013-01-02 2 views
1

제거 방법방법 I이 방법을 가지고 세실 명령

I 이렇게 그래서 목적어 생성을 매개 변수로 입력을 전달하고 제거 할 수있는 IL 주사를 사용하여 변경할 필요
public int Test() 
{ 
    ExternalClass cls = new ExternalClass(); 
    return cls.ExternalMethod(); 
} 

:

public int Test(ExternalClass cls) 
{ 

    return cls.ExternalMethod(); 
} 

나는 새로운 국회를 사용하여 추가 parametr을 <> .Parameters.Add (_ ___) 추가하고 생성 할 수 있어요.

문제는 새 개체 생성에 대한 지침을 제거 할 수 없다는 것입니다. 아래는 내가 그것을 제거하는 데 사용되는 라인입니다.

ILProcessor ilProcessor = <<MethodDefinition>>.Body.GetILProcessor(); 
ilProcessor.Remove(<<newobj instruction>>); 

아래와 같이 수정 된 어셈블리 메서드를 호출하면 "공용 언어 런타임에서 잘못된 프로그램을 발견했습니다."라는 오류가 발생합니다.

ExternalClass ext = new ExternalClass(); 
int i = prg1.Test(ext); 

메모리 할당과 관련된 문제도 처리해야 할 수도 있습니다. 아무도 여기에 구현할 추가 단계를 제공 할 수 있다면 고맙겠습니다.

답변

6

newobj 명령어를 제거 할 수는 없습니다. 런타임에서 말한 것처럼 잘못된 프로그램이 남아 있습니다. 여기에 원래 방법은 IL로 변환 대략 방법은 다음과 같습니다

public Int32 Test() 
{ 
    .local ExternalClass 0; 

    // ExternalClass cls = new ExternalClass(); 
    newobj class ExternalClass(); 
    stloc.0; 

    // return cls.ExternalMethod(); 
    ldloc.0; 
    callvirt Int32 class ExternalClass:ExternalMethod(); 
    ret; 
} 

경우에만 newobj 명령을 제거하면 다음 stloc 명령은 로컬에 저장하는 스택에 아무것도 없습니다. 이에 방법을 설정해야합니다

public Int32 Test(ExternalClass cls) 
{ 
    // return cls.ExternalMethod(); 
    ldarg.1; 
    callvirt Int32 class ExternalClass:ExternalMethod(); 
    ret; 
} 

그래서 당신이 세 가지를 수행해야합니다

  1. 이 메소드 서명에 인수 추가하기,
  2. 에 모든 것을 제거하고ldloc 지시.
  3. ldarg.1 명령을 메서드 시작 부분에 삽입하십시오.

선택적으로 로컬 ExternalClass도 제거 할 수 있습니다. (이것은 JIT 컴파일러에 의해 최적화 될 것이지만 IL 이미지를 부 풀릴 것입니다.)

+0

로컬을 계속 사용하고'newobj'를'ldarg'로 바꾸는 것이 더 간단하지 않습니까? – svick

+0

@svick 다른 가능한 접근 방법이 될 수 있습니다. – cdhowie

+0

감사합니다. 더 많은 논의가 통과되면 언급 된 추가 챈이 그에 따라 증가 할 수 있기를 바랍니다. –