summaryrefslogtreecommitdiff
path: root/src/bindings/mono/eo_mono/iwrapper.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/bindings/mono/eo_mono/iwrapper.cs')
-rw-r--r--src/bindings/mono/eo_mono/iwrapper.cs39
1 files changed, 31 insertions, 8 deletions
diff --git a/src/bindings/mono/eo_mono/iwrapper.cs b/src/bindings/mono/eo_mono/iwrapper.cs
index e761935892..421ce189fe 100644
--- a/src/bindings/mono/eo_mono/iwrapper.cs
+++ b/src/bindings/mono/eo_mono/iwrapper.cs
@@ -790,21 +790,44 @@ public static class Globals
return wrappedAccessor.Handle;
}
- var list = new List<IntPtr>();
+ // TODO: Check if we're either an Eina.List or Eina.Collection?
+ // We could just rewrap their native accessors
+ IntPtr[] intPtrs = new IntPtr[enumerable.Count()];
+
+ int i = 0;
foreach (T data in enumerable)
{
- list.Add(Eina.TraitFunctions.ManagedToNativeAlloc<T>(data));
+ intPtrs[i] = Eina.TraitFunctions.ManagedToNativeAlloc<T>(data);
+ i++;
}
- IntPtr[] dataArray = list.ToArray();
- GCHandle pinnedArray = GCHandle.Alloc(dataArray, GCHandleType.Pinned); //FIXME: Need to free.
- IntPtr ret = Eina.AccessorNativeFunctions.eina_carray_length_accessor_new(pinnedArray.AddrOfPinnedObject(), (uint)(IntPtr.Size), (uint)dataArray.Length);
- if (!isMoved)
+ IntPtr[] dataArray = intPtrs.ToArray();
+ GCHandle pinnedArray = GCHandle.Alloc(dataArray, GCHandleType.Pinned);
+
+ IntPtr nativeAccessor = IntPtr.Zero;
+
+ if (isMoved)
{
- // FIXME Need to free ret and unpin pinnedArray in the future.
+ // We need a custom accessor that would unpin the data when freed.
+ nativeAccessor = Eina.AccessorNativeFunctions.eina_mono_owned_carray_length_accessor_new(pinnedArray.AddrOfPinnedObject(),
+ (uint)IntPtr.Size,
+ (uint)dataArray.Length,
+ free_gchandle,
+ GCHandle.ToIntPtr(pinnedArray));
+ }
+ else
+ {
+ // FIXME: Leaking....
+ nativeAccessor = Eina.AccessorNativeFunctions.eina_carray_length_accessor_new(pinnedArray.AddrOfPinnedObject(), (uint)(IntPtr.Size), (uint)dataArray.Length);
}
- return ret;
+ if (nativeAccessor == IntPtr.Zero)
+ {
+ pinnedArray.Free();
+ throw new InvalidOperationException("Failed to get native accessor for the given container");
+ }
+
+ return nativeAccessor;
}
internal static IEnumerable<T> IteratorToIEnumerable<T>(IntPtr iterator)