diff --git a/wrappers/csharp/genwrapper.py b/wrappers/csharp/genwrapper.py
index 05444e88c..cc1491c5e 100644
--- a/wrappers/csharp/genwrapper.py
+++ b/wrappers/csharp/genwrapper.py
@@ -331,12 +331,13 @@ class CsharpTranslator(object):
listenerDict = {}
c_name_setter = listenedClass.name.to_snake_case(fullName=True) + '_cbs_set_' + method.name.to_snake_case()[3:]
- listenerDict['cb_setter'] = {}
- listenerDict['cb_setter']['name'] = c_name_setter
-
- listenerDict['delegate'] = {}
delegate_name_public = method.name.to_camel_case() + "Delegate"
delegate_name_private = delegate_name_public + "Private"
+ listenerDict['cb_setter'] = {}
+ listenerDict['cb_setter']['name'] = c_name_setter
+ listenerDict['name_private'] = delegate_name_private
+
+ listenerDict['delegate'] = {}
listenerDict['delegate']['name_public'] = delegate_name_public
listenerDict['delegate']['name_private'] = delegate_name_private
var_name_public = method.name.to_snake_case() + '_public'
@@ -346,6 +347,9 @@ class CsharpTranslator(object):
listenerDict['delegate']['cb_name'] = method.name.to_snake_case()
listenerDict['delegate']['name'] = method.name.to_camel_case()
+ listenerDict['delegate']['interfaceClassName'] = listenedClass.name.to_camel_case()
+ listenerDict['delegate']['isSimpleListener'] = not listenedClass.multilistener
+ listenerDict['delegate']['isMultiListener'] = listenedClass.multilistener
listenerDict['delegate']['params_public'] = ""
listenerDict['delegate']['params_private'] = ""
@@ -359,6 +363,9 @@ class CsharpTranslator(object):
listenerDict['delegate']['params_public'] += ', '
listenerDict['delegate']['params_private'] += ', '
listenerDict['delegate']['params'] += ', '
+ else:
+ listenerDict['delegate']['first_param'] = argName
+
if normalType == dllImportType:
listenerDict['delegate']['params'] += argName
else:
@@ -570,6 +577,7 @@ def main():
parser = AbsApi.CParser(project)
parser.functionBl = ['linphone_vcard_get_belcard']
parser.classBl += 'LinphoneCoreVTable'
+ parser.methodBl.remove('getCurrentCallbacks')
parser.parse_all()
translator = CsharpTranslator()
renderer = pystache.Renderer()
diff --git a/wrappers/csharp/wrapper_impl.mustache b/wrappers/csharp/wrapper_impl.mustache
index b3571e127..8a439adff 100644
--- a/wrappers/csharp/wrapper_impl.mustache
+++ b/wrappers/csharp/wrapper_impl.mustache
@@ -20,16 +20,21 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
+using ObjCRuntime;
namespace Linphone
{
- #region Wrapper specifics
+#region Wrapper specifics
///
/// Only contains the LIB_NAME value that represents the library in which all DllImport are made
///
public class LinphoneWrapper
{
+#if ANDROID
public const string LIB_NAME = "linphone"; // With this, it automatically finds liblinphone.so
+#else
+ public const string LIB_NAME = "linphone.framework/linphone";
+#endif
}
///
@@ -52,8 +57,11 @@ namespace Linphone
{
internal IntPtr nativePtr;
- [DllImport(LinphoneWrapper.LIB_NAME)]
- static extern int belle_sip_object_data_set(IntPtr ptr, string name, IntPtr data, IntPtr cb);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ private delegate void OnLinphoneObjectDataDestroyed(IntPtr data);
+
+ [DllImport(LinphoneWrapper.LIB_NAME)]
+ static extern int belle_sip_object_data_set(IntPtr ptr, string name, IntPtr data, OnLinphoneObjectDataDestroyed cb);
[DllImport(LinphoneWrapper.LIB_NAME)]
static extern IntPtr belle_sip_object_data_get(IntPtr ptr, string name);
@@ -75,6 +83,17 @@ namespace Linphone
[DllImport(LinphoneWrapper.LIB_NAME)]
static extern IntPtr bctbx_list_append(IntPtr elem, IntPtr data);
+
+ [MonoPInvokeCallback(typeof(OnLinphoneObjectDataDestroyed))]
+ private static void onDataDestroyed(IntPtr data)
+ {
+ if (data != IntPtr.Zero)
+ {
+ //Console.WriteLine("Freeing C# handle");
+ GCHandle handle = GCHandle.FromIntPtr(data);
+ handle.Free();
+ }
+ }
~LinphoneObject()
{
@@ -99,14 +118,18 @@ namespace Linphone
//Console.WriteLine("Reffing" + obj.ToString());
}
obj.nativePtr = ptr;
- objPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(T)));
- Marshal.StructureToPtr(obj, objPtr, false);
- belle_sip_object_data_set(ptr, "cs_obj", objPtr, IntPtr.Zero);
+ /*objPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(T)));
+ Marshal.StructureToPtr(obj, objPtr, false);*/
+ GCHandle handle = GCHandle.Alloc(obj);
+ objPtr = GCHandle.ToIntPtr(handle);
+ belle_sip_object_data_set(ptr, "cs_obj", objPtr, onDataDestroyed);
return obj;
}
else
{
- T obj = Marshal.PtrToStructure(objPtr);
+ //T obj = Marshal.PtrToStructure(objPtr);
+ GCHandle handle = GCHandle.FromIntPtr(objPtr);
+ T obj = (T)handle.Target;
if (takeRef)
{
obj.nativePtr = belle_sip_object_ref(obj.nativePtr);
@@ -240,7 +263,7 @@ namespace Linphone
{{#methods}}
[DllImport(LinphoneWrapper.LIB_NAME)]
{{#cb_setter}}
- static extern void {{name}}(IntPtr thiz, IntPtr cb);
+ static extern void {{name}}(IntPtr thiz, {{name_private}} cb);
{{/cb_setter}}
{{#delegate}}
@@ -248,13 +271,17 @@ namespace Linphone
private delegate void {{name_private}}({{params_private}});
public delegate void {{name_public}}({{params_public}});
- private {{name_private}} {{var_private}};
private {{name_public}} {{var_public}};
- private void {{cb_name}}({{params_private}})
+ [MonoPInvokeCallback(typeof({{name_private}}))]
+ private static void {{cb_name}}({{params_private}})
{
- {{var_public}}?.Invoke({{{params}}});
+ {{interfaceClassName}} thiz = fromNativePtr<{{interfaceClassName}}>({{first_param}});
+ {{#isSimpleListener}}{{interfaceName}} listener = thiz.Listener;{{/isSimpleListener}}
+ {{#isMultiListener}}{{interfaceName}} listener = thiz.CurrentCallbacks;{{/isMultiListener}}
+ listener.{{var_public}}?.Invoke({{{params}}});
}
+
public {{name_public}} {{name}}
{
get
@@ -263,10 +290,8 @@ namespace Linphone
}
set
{
- {{var_private}} = {{cb_name}};
{{var_public}} = value;
- IntPtr cb = Marshal.GetFunctionPointerForDelegate({{var_private}});
- {{c_name_setter}}(nativePtr, cb);
+ {{c_name_setter}}(nativePtr, {{cb_name}});
}
}
{{/delegate}}