[Mono-dev] Returning small structs from internal calls?

Aras Pranckevicius aras at otee.dk
Tue Dec 12 08:55:09 EST 2006


We have some trouble returning small (<= byte) structs from our native
code to Mono via internal calls on x86 (both PC and OS X). All the
documentation and real code I could find in Mono does not do this; it
returns either void or primitive types. To me it looks like when
invoking icall, Mono is not pushing the arguments correctly, but I'm
not sure because these days my asm skills are quite rusty :)

Basically, if we have a struct Vector2 { float x, y; } in C++ code,
the equivalent struct in C# code and have an internall call such as:

    // native code
    static Vector2 Material_GetTextureOffset(
        Reference<Material> self, MonoString* name)
      return ...;
    // later on register it
    mono_add_internal_call( "UnityEngine.Material::Internal_GetTextureOffset",

    // C# code
    [MethodImplAttribute (MethodImplOptions.InternalCall)]
    private extern static Vector2 Internal_GetTextureOffset (Material
self, string name);

Then when native code is called, the arguments seem to be all wrong.
Similar code that uses larger structs (more than 8 bytes) works.

We observe this in Mono 1.2, both built with gcc (OS X) and visual
studio 2003 (Windows). There is no problem on PPC machines (OS X).

My first blind guess - does it have to do something with small structs
being returned in registers by most compilers instead of the stack?
Maybe Mono JIT always generates code as if all structs would be
returned on the stack?

Aras Pranckevicius
Graphics programmer at unity3d.com

More information about the Mono-devel-list mailing list