[Mono-list] passing MonoArray from c#

fozzie david_aiken at yahoo.com
Sat May 2 13:12:47 EDT 2009


ok.. I've modified the example as follows, but the DataLink data is NULL on
return. Maybe there is confusion because the c# Invoke() method returns an
object but the Pack() method, which it calls, returns Link[]?


fozzie wrote:
> 
> This is the C# code which is called:
> 
>    
> [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Explicit)]
>     [Serializable]
>     public struct Data
>     {
>         [System.Runtime.InteropServices.FieldOffsetAttribute(0)]
>         public int i;
> 
>         [System.Runtime.InteropServices.FieldOffsetAttribute(0)]
>         public System.IntPtr s;
> 
>         [System.Runtime.InteropServices.FieldOffsetAttribute(0)]
>         public float f;
>     }
> 
>    
> [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
>     [Serializable]
>     public struct Link
>     {
>         public int type;
>         public Data data;
>     }
> 
>     public enum DataType { DT_Int = 0, DT_String = 1, DT_Float = 2 };
> 
>     public class Widget : Controller
>     {
>         public override Link[] Pack(System.UInt32 packFlags)
>         {
>             Link[] links = new Link[2];
>             links[0].type = (int)DataType.DT_Float;
>             links[0].data.f = mMass;
>             links[1].type = (int)DataType.DT_String;
> 
            //links[1].data.s = mName;
            links[1].data.s = Marshal.StringToHGlobalUni(mName);

fozzie wrote:
> 
> 
>             return links; // TBD is this valid until the C++ side is done
> with it?
>         }
> 
>         public override object Invoke(string methodName, object[]
> parameters)
>         {
>             return this.GetType().InvokeMember(methodName,
> BindingFlags.InvokeMethod, null, this, parameters);
>         }
>     }
> 
> This is the calling C++ code.. the debugger output shows that the
> Widget:Pack call gets the packFlags parameter correctly and exits:
> 
>         typedef enum {DT_Int = 0, DT_String = 1, DT_Float = 2} DataType;
> // has to match type in Controllers.cs
> 
>         typedef union 
>         {
>             int i;
>             WCHAR *s;
>             float f;
>         }Data;
> 
>         typedef struct
>         {
>             int type;
>             Data data;
>         }DataLink;
> 
>         MonoArray *args = mono_array_new(domain, mono_get_object_class(),
> 1);
>         MonoObject *result = mono_value_box (domain, mono_get_uint32_class
> (), &packFlags);
>         mono_array_setref (args, 0, result);
> 
        //MonoObject *retVal = mMonoClass->invoke("Pack", args);
        //MonoArray *retLinks = (MonoArray *)mono_object_unbox(retVal);
     MonoArray *retLinks = (MonoArray *)mMonoClass->invoke("Pack", args);
     DataLink *link = (DataLink*)mono_array_get(retLinks, DataLink*, 0);

Unfortunately the link is NULL. The memory pointed to by retLinks does not
contain valid DataLink data.
Out of curiosity, do you know what the lifetime of the data returned by
invoke() is? Is it safe to keep referencing it via pointers after the call
has finished? How is it freed? 


-- 
View this message in context: http://www.nabble.com/passing-MonoArray-from-c--tp23341741p23348386.html
Sent from the Mono - General mailing list archive at Nabble.com.



More information about the Mono-list mailing list