MODLANG-165 Added wrapper for switch_event_bind for .net

This commit is contained in:
Jeff Lenk 2010-06-01 10:23:04 -05:00
parent 4fa8be625a
commit a5f07a8066
2 changed files with 120 additions and 0 deletions

View File

@ -0,0 +1,119 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_managed
* Copyright (C) 2008, Michael Giagnocavo <mgg@giagnocavo.net>
*
* Version: MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_managed
*
* The Initial Developer of the Original Code is
* Michael Giagnocavo <mgg@giagnocavo.net>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Michael Giagnocavo <mgg@giagnocavo.net>
*
* EventBinding.cs - Helpers for switch_event_bind function
*
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Reflection;
using FreeSWITCH.Native;
namespace FreeSWITCH
{
public class EventBinding : IDisposable
{
public class EventBindingArgs : EventArgs
{
public switch_event EventObj { get; set; }
}
//typedef void (*switch_event_callback_t) (switch_event_t *);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate void switch_event_callback_delegate(IntPtr event_data);
readonly switch_event_callback_delegate del; // Prevent GC
readonly SWIGTYPE_p_f_p_switch_event__void function;
private EventBinding(SWIGTYPE_p_f_p_switch_event__void function, switch_event_callback_delegate origDelegate)
{
this.function = function;
this.del = origDelegate;
}
bool disposed;
public void Dispose()
{
dispose();
GC.SuppressFinalize(this);
}
void dispose()
{
if (disposed) return;
// HACK: FS crashes if we unbind after shutdown is pretty complete. This is still a race condition.
if (freeswitch.switch_core_ready() == switch_bool_t.SWITCH_FALSE) return;
freeswitch.switch_event_unbind_callback(this.function);
disposed = true;
}
~EventBinding()
{
dispose();
}
public static switch_event SwitchEventDupe(switch_event evt)
{
IntPtr clone_ptr_ptr = Marshal.AllocCoTaskMem(IntPtr.Size);
freeswitch.switch_event_dup(new SWIGTYPE_p_p_switch_event(clone_ptr_ptr, false), evt);
IntPtr event_ptr = (IntPtr)Marshal.PtrToStructure(clone_ptr_ptr, typeof(IntPtr));
switch_event dupe_evt = new switch_event(event_ptr, false);
Marshal.FreeCoTaskMem(clone_ptr_ptr);
return dupe_evt;
}
public static IDisposable Bind(string id, switch_event_types_t event_types, string subclass_name, Action<EventBindingArgs> f, bool dupe)
{
switch_event_callback_delegate boundFunc;
if (dupe)
{
boundFunc = (eventObj) =>
{
var args = new EventBindingArgs { EventObj = SwitchEventDupe(new switch_event(eventObj,false)) };
f(args);
};
}
else
{
boundFunc = (eventObj) =>
{
var args = new EventBindingArgs { EventObj = new switch_event(eventObj, false) };
f(args);
};
}
var fp = Marshal.GetFunctionPointerForDelegate(boundFunc);
var swigFp = new SWIGTYPE_p_f_p_switch_event__void(fp, false);
var res = freeswitch.switch_event_bind(id, event_types, subclass_name, swigFp, null);
if (res != switch_status_t.SWITCH_STATUS_SUCCESS)
{
throw new InvalidOperationException("Call to switch_event_bind failed, result: " + res + ".");
}
return new EventBinding(swigFp, boundFunc);
}
}
}

View File

@ -49,6 +49,7 @@
<ItemGroup>
<Compile Include="AssemblyInfo.cs" />
<Compile Include="ChannelVariables.cs" />
<Compile Include="EventBinding.cs" />
<Compile Include="ManagedSession.cs" />
<Compile Include="Loader.cs" />
<Compile Include="Extensions.cs" />