[Mono-list] Embedded API: Boxing value types and ToString

Aaron Oneal aaron.oneal at spicypixel.com
Tue Jul 23 23:42:59 UTC 2013


I had a look at the mono_object_to_string implementation and it may need to be updated to support value types. It relies on mono_runtime_invoke which expects value types to be passed as a pointer to the value type, not as a MonoObject pointer. I believe it could be fixed as follows.

MonoString *
mono_object_to_string (MonoObject *obj, MonoObject **exc)
{
    static MonoMethod *to_string = NULL;
    MonoMethod *method;

    g_assert (obj);

    if (!to_string)
        to_string = mono_class_get_method_from_name_flags (mono_get_object_class (), "ToString", 0, METHOD_ATTRIBUTE_VIRTUAL | METHOD_ATTRIBUTE_PUBLIC);

    method = mono_object_get_virtual_method (obj, to_string);

    // Unbox value type if needed
    void *target = obj;
    if (mono_class_is_valuetype (mono_method_get_class (method))) {
        target = mono_object_unbox(obj);
    }
    
    return (MonoString *) mono_runtime_invoke (method, target, NULL, exc);
}

On Jul 23, 2013, at 4:06 PM, Aaron Oneal <aaron.oneal at spicypixel.com> wrote:

> I ran the simple boxing test below on Mono 2.10.12 and 3.1.2 and don't understand why the ToString results on the boxed object do not match the unboxed value.
> 
> I can also pass the MonoObject into mono_runtime_invoke to have a C# method on the other side call ToString and it shows the correct value.
> 
> Is there a known issue with mono_object_to_string or am I doing something incorrectly?
> 
> Thanks!
> 
> // Int Marshalling
> int32_t v = 10;
> printf("original value = %d\n", v);
> 
> MonoObject *obj = mono_value_box(mono_domain_get(), mono_get_int32_class(), &v);
> MonoString *obj_string = mono_object_to_string(obj, NULL);
> char *obj_string_utf8 = mono_string_to_utf8(obj_string);
> printf("boxed value = %s\n", obj_string_utf8);
> g_free(obj_string_utf8);
> 
> v = *(int32_t*)mono_object_unbox(obj);
> printf("unboxed value = %d\n", v);
> 
> // Output
> // original value = 10
> // boxed value = 85441552   <-- Huh?
> // unboxed value = 10
> 
> 
> // Bool Marshalling
> int8_t b = 0;
> printf("original value = %d\n", b);
> 
> obj = mono_value_box(mono_domain_get(), mono_get_boolean_class(), &b);
> obj_string = mono_object_to_string(obj, NULL);
> obj_string_utf8 = mono_string_to_utf8(obj_string);
> printf("boxed value = %s\n", obj_string_utf8);
> g_free(obj_string_utf8);
> 
> b = *(int8_t*)mono_object_unbox(obj);
> printf("unboxed value = %d\n", b);
> 
> // Output
> // original value = 0
> // boxed value = True   <-- 0 == True ?
> // unboxed value = 0
> _______________________________________________
> Mono-list maillist  -  Mono-list at lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-list

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.ximian.com/pipermail/mono-list/attachments/20130723/1dfccb09/attachment-0001.html>


More information about the Mono-list mailing list