Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

System.Reflection - Global methods aren't available for reflection

System.Reflection does not (AFAIK) support reflecting on global methods in an assembly. At the assembly level, I must start with the root types.

My compiler can produce assemblies with global methods, and my standard bootstrap lib is a dll that includes some global methods. My compiler uses System.Reflection to import assembly metadata at compile time. It seems if I depend on System.Reflection, global methods are not a possibility. The cleanest solution is to convert all of my standard methods to class static methods, but the point is, my language allows global methods, and the CLR supports it, but System.Reflection leaves a gap.

ildasm shows the global methods just fine, but I assume it does not use System.Reflection itself and goes right to the metadata and bytecode.

Besides System.Reflection, is anyone aware of any other 3rd party reflection or disassembly libs that I could make use of (assuming I will eventually release my compiler as free, BSD licensed open source).

SOLVED: There is no gap, except in my knowledge. Thanks for pointing out GetModules, guys!

like image 493
codenheim Avatar asked Apr 22 '10 21:04

codenheim


3 Answers

Have you looked at Module.GetMethods?

Returns the global methods defined on the module

You can get all the modules of your assembly using Assembly.GetModules().

like image 59
Jon Skeet Avatar answered Oct 11 '22 17:10

Jon Skeet


You keep beating on a gap between the CLR and System.Reflection, but actually, there's no such thing as a global method or a global field.

They are just traditional static methods and static fields that are defined in particular type, named <Module>, which has to be present in every valid assembly.

As Jon said, you can use Module.GetMethod and Module.GetField to operator on the members of the type.

If you want more control, you can just use Mono.Cecil.

like image 29
Jb Evain Avatar answered Oct 11 '22 15:10

Jb Evain


Note, that Module.GetMethod() without parameters won't return all module's methods.
Use GetMethods(BindingFlags) instead.

C++/CLI example:

#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)));
}
like image 37
Abyx Avatar answered Oct 11 '22 17:10

Abyx