2010-04-22 5 views
5

System.Reflection은 어셈블리의 전역 메서드를 반영하지 않습니다 (AFAIK). 어셈블리 레벨에서 루트 유형으로 시작해야합니다.System.Reflection - 리플렉션에 전역 메서드를 사용할 수 없습니다.

내 컴파일러는 전역 메서드를 사용하여 어셈블리를 생성 할 수 있으며 내 표준 부트 스트랩 lib는 일부 전역 메서드가 포함 된 dll입니다. 내 컴파일러는 System.Reflection을 사용하여 컴파일 타임에 어셈블리 메타 데이터를 가져옵니다. System.Reflection에 의존한다면 글로벌 메소드가 가능하지 않은 것 같습니다. 가장 깨끗한 솔루션은 모든 표준 메서드를 클래스 정적 메서드로 변환하는 것이지만 내 언어는 전역 메서드를 허용하고 CLR은이를 지원하지만 System.Reflection은 갭을 남깁니다.

ildasm은 전역 메서드를 잘 보여 주지만 System.Reflection 자체를 사용하지 않고 메타 데이터 및 바이트 코드로 바로 이동한다고 가정합니다.

System.Reflection 외에도 다른 모든 타사 리플렉션 또는 디스 어셈블리 라이브러리를 알고있는 사람이 있습니다. (결국 무료로 제공되는 BSD 라이센스 오픈 소스로 내 컴파일러를 릴리스 할 것이라고 가정합니다.)

해결 : 내 지식을 제외하고는 틈이 없습니다. GetModules를 지적 해 주셔서 감사합니다, 얘들 아!

답변

9

Module.GetMethods을 보았습니까?

모듈

당신은 Assembly.GetModules()를 사용하여 어셈블리의 모든 모듈을 얻을 수에 정의 된 글로벌 방법을 돌려줍니다.

+0

그것에 나를 이길하지만 내가 실제로 그것을 시도하지 않은 것을 인정해야한다. 좋은 질문과 좋은 대답. –

+1

@ 브라이언 : 왜 내가 그걸 해봤다고 생각하니? ;) –

+0

당신은 문서가 정확하고보기 만해도 알 수있는 높은 수준의 힘을 가지고있을 것입니다 :) –

4

CLR과 System.Reflection 사이의 차이점을 계속 깨지 만 실제로는 전역 메서드 또는 전역 필드와 같은 것이 없습니다.

이들은 단지 전통적인 정적 메서드이고 모든 유효한 어셈블리에 있어야하는 특정 유형의 정의 된 필드 인 <Module>입니다.

Jon이 말했듯이 Module.GetMethodModule.GetField을 사용하여 해당 유형의 멤버에 대해 연산자를 사용할 수 있습니다.

더 많은 제어가 필요한 경우 Mono.Cecil을 사용할 수 있습니다.

+1

+1 Mono.Cecil은 좋습니다! –

+1

저는 키보드를 제외하고는 "아무 것도 할 수 없습니다". 방금이 정보를 놓쳤습니다. 그래서 내가 왜 그렇게 물었습니다. 매일 더 많이 배웁니다. 답변 해주셔서 감사합니다. :) – codenheim

+0

@ Jb : Mono.Cecil에 관해서는, 나는 그것을 알고 있으며 확실하게 그것에 관심이 있습니다. 내가 그걸 통과 한 유일한 이유는 면허 였어. 코드를 공개하면 BSD 라이센스가됩니다.Mono와의 관계 구축을 지원할 예정이지만 공식 CLR 및 Mono에 공통적이지 않은 도구에는 의존 할 수 없습니다. 물론, 어쨌든 모든 투기가 지금 당장 있습니다. – codenheim

2

매개 변수가없는 Module.GetMethod()은 모든 모듈의 메서드를 반환하지 않습니다.
GetMethods (BindingFlags)를 대신 사용하십시오.

C++/CLI 예 :

#using <System.dll> 
using namespace System; 
using namespace System::Reflection; 
using namespace System::Diagnostics; 

bool has_main(array<MethodInfo^>^ methods) 
{ 
    for each(auto m in methods) 
     if(m->Name == "main") 
      return true; 
    return false; 
} 

int main() 
{ 
    auto module = Assembly::GetExecutingAssembly()->GetModules(false)[0]; 
    Debug::Assert(has_main(module->GetMethods()) == false); 
    Debug::Assert(has_main(module->GetMethods(BindingFlags::Static | BindingFlags::NonPublic))); 
} 
관련 문제