1

Why can't I get the MonoMethod* for the method that takes an enum,
and is there a way to list the methods that mono knows about?

Here's a reduced example of what I'm trying to do. I tried different combinations of what (Windows) ildasm reported but no success.

// enum.cs
namespace EnumTest
{
    class EnumClass
    {
        public enum HelloType { Hi, Hey, Howdy, Greetings, Aloha };

        public static void SetDefault() { type_ = HelloType.Hi; }

        public static void SetType(HelloType h) { type_ = h; }

        public static HelloType type_;
    }
}

// enum.cpp
#include <mono/jit/jit.h>
#include <mono/metadata/assembly.h>
#include <mono/metadata/debug-helpers.h>

int main(int argc, char* argv[]) {
  MonoDomain* domain = mono_jit_init("enum.dll");
  MonoAssembly* assembly = mono_domain_assembly_open(domain, "enum.dll");
  MonoImage* image = mono_assembly_get_image(assembly);
  MonoClass* enumClass = mono_class_from_name(image, "EnumTest", "EnumClass");

  MonoMethodDesc* defaultDesc = mono_method_desc_new("EnumTest.EnumClass:SetDefault()", false);
  MonoMethod* defaultMethod = mono_method_desc_search_in_class(defaultDesc, enumClass);

  printf("defaultDesc from mono_method_desc_new() is %p\n", defaultDesc);
  printf("defaultMethod from mono_method_desc_search_in_class() is %p\n\n", defaultMethod);


  MonoMethodDesc* typeDesc = mono_method_desc_new("EnumTest.EnumClass:SetType(HelloType)", false);
  MonoMethod* typeMethod = mono_method_desc_search_in_class(typeDesc, enumClass);

  printf("typeDesc from mono_method_desc_new() is %p\n", typeDesc);
  printf("typeMethod from mono_method_desc_search_in_class() is %p      <------\n", typeMethod);


  mono_jit_cleanup(domain);
}

$ mcs /nologo /warn:4 /debug:pdbonly /o  /out:enum.dll /target:library enum.cs
$ gcc enum.cpp -g3 `pkg-config --cflags --libs mono-2` -o enum
$ ./enum
defaultDesc from mono_method_desc_new() is 0x1443920
defaultMethod from mono_method_desc_search_in_class() is 0x13dce40

typeDesc from mono_method_desc_new() is 0x1444590
typeMethod from mono_method_desc_search_in_class() is (nil)      <------
$ uname -a
Linux U14-OOXML 3.16.0-37-generic #51~14.04.1-Ubuntu SMP Wed May 6 15:23:14 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
2
  • Try iterating all of the class methods with mono_class_get_methods - does the method show up there? Commented May 21, 2015 at 7:50
  • The method in question (SetType) shows up when iterating with mono_class_get_methods(). And using mono_method_signature(), mono_signature_get_params() and mono_type_get_name() shows that internally mono know its parameter type to be EnumTest.EnumClass.HelloType So it would seem that my above code is correct. Commented May 21, 2015 at 16:32

1 Answer 1

1

Looks like the parameter type requires the full type name.

I used mono_method_full_name with the second argument signature true to get the signature (I used my own test class with identical structure but different names):

MonoDomain* domain = mono_jit_init(CSHARP_LIB);
MonoAssembly* assembly = mono_domain_assembly_open(domain, CSHARP_LIB);
MonoImage* image = mono_assembly_get_image(assembly);
MonoClass* sandboxClass = mono_class_from_name(image, "CSharp_ClassLibrary", "Sandbox");

void* ptr = 0;
MonoMethod* iter;

while ((iter = mono_class_get_methods(sandboxClass, &ptr)) != NULL)
{
    printf("--------------------------------\n");
    const char* name = mono_method_get_name(iter);
    MonoMethodDesc* methodDesc = mono_method_desc_from_method(iter);

    const char* paramNames = "";
    mono_method_get_param_names(iter, &paramNames);

    printf("Name: %s\n", name);
    printf("Full name: %s\n", mono_method_full_name(iter, true));
    printf("    namespace: %s\n", methodDesc ->namespace);
    printf("    class:     %s\n", methodDesc ->klass);
    printf("    name:      %s\n", methodDesc ->name);
    printf("    args:      %s\n", methodDesc ->args);
    printf("    num_args:  %d\n", methodDesc ->num_args);
    printf("    paramnames:%s\n", paramNames);
}

The output I received was this:

--------------------------------
Name: SetDefault
Full name: CSharp_ClassLibrary.Sandbox:SetDefault ()
    namespace: CSharp_ClassLibrary
    class:     Sandbox
    name:      SetDefault
    args:      (null)
    num_args:  0
    paramnames:
--------------------------------
Name: SetType
Full name: CSharp_ClassLibrary.Sandbox:SetType (CSharp_ClassLibrary.Sandbox/HelloType)
    namespace: CSharp_ClassLibrary
    class:     Sandbox
    name:      SetType
    args:      (null)
    num_args:  0
    paramnames:h
--------------------------------
Name: .ctor
Full name: CSharp_ClassLibrary.Sandbox:.ctor ()
    namespace: CSharp_ClassLibrary
    class:     Sandbox
    name:      .ctor
    args:      (null)
    num_args:  0
    paramnames:

So to fix your code, you'd just add the class name before the parameter type:

MonoMethodDesc* typeDesc = mono_method_desc_new("EnumTest.EnumClass:SetType(EnumClass/HelloType)", false);
MonoMethod* typeMethod = mono_method_desc_search_in_class(typeDesc, enumClass);

This, at least for me, works just fine!

Sign up to request clarification or add additional context in comments.

5 Comments

your example code is not Not exactly correct, mono_method_get_param_names. your code will cause stack crash. try:const char* paramNames[128] = { 0 }; mono_method_get_param_names(iter, paramNames);
Accessing methodDesc members gives compiler error - member access into incomplete type.
@awattar This answer was written in 2015. The Mono API has probably had major changes since then.
I've assumed that but also have searched back in the history of the github.com/mono/mono/blob/main/mono/metadata/debug-helpers.h and didn't find MonoMethodDesc struct be ever fully defined public.
I see. There's probably corresponding functions in mono/metadata/class.h for getting the fields. Feel free to suggest an edit or leave a new, up to date answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.