P/Invoke should do all the work for us

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@9797 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Michael Giagnocavo 2008-10-02 18:59:09 +00:00
parent b66e1bad4c
commit 657a0c9ac0
4 changed files with 21 additions and 15 deletions

View File

@ -74,9 +74,6 @@ ManagedSession::~ManagedSession()
// Don't let any callbacks use this CoreSession anymore // Don't let any callbacks use this CoreSession anymore
switch_channel_set_private(channel, "CoreSession", NULL); switch_channel_set_private(channel, "CoreSession", NULL);
} }
// Free delegates
hangupDelegateHandle.Free();
dtmfDelegateHandle.Free();
} }
bool ManagedSession::begin_allow_threads() bool ManagedSession::begin_allow_threads()
@ -91,22 +88,23 @@ bool ManagedSession::end_allow_threads()
void ManagedSession::check_hangup_hook() void ManagedSession::check_hangup_hook()
{ {
if (!hangupDelegateHandle.IsAllocated) { if (!hangupDelegate) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "hangupDelegateHandle didn't get an object."); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "hangupDelegateHandle didn't get an object.");
return; return;
} }
((HangupDelegate^)hangupDelegateHandle.Target)(); hangupDelegate();
} }
switch_status_t ManagedSession::run_dtmf_callback(void *input, switch_input_type_t itype) switch_status_t ManagedSession::run_dtmf_callback(void *input, switch_input_type_t itype)
{ {
if (!dtmfDelegateHandle.IsAllocated) { if (!dtmfDelegate) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "dtmfDelegateHandle didn't get an object."); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "dtmfDelegateHandle didn't get an object.");
return SWITCH_STATUS_FALSE;; return SWITCH_STATUS_FALSE;;
} }
char *result = ((InputDelegate^)dtmfDelegateHandle.Target)(input, itype); char *result = dtmfDelegate(input, itype);
switch_status_t status = process_callback_result(result); switch_status_t status = process_callback_result(result);
Marshal::FreeHGlobal(IntPtr(result)); // I think this is right
return status; return status;
} }

View File

@ -99,8 +99,8 @@ using namespace System;
using namespace System::Reflection; using namespace System::Reflection;
using namespace System::Runtime::InteropServices; using namespace System::Runtime::InteropServices;
delegate void HangupDelegate(void); typedef void (*hangupFunction)(void);
delegate char* InputDelegate(void* input, switch_input_type_t type); typedef char* (*inputFunction)(void*, switch_input_type_t);
public ref class FreeSwitchManaged public ref class FreeSwitchManaged
{ {
@ -130,8 +130,9 @@ public:
virtual switch_status_t run_dtmf_callback(void *input, switch_input_type_t itype); virtual switch_status_t run_dtmf_callback(void *input, switch_input_type_t itype);
#ifdef _MANAGED #ifdef _MANAGED
GCHandle dtmfDelegateHandle; // GCHandle to the input delegate // P/Invoke function pointer to delegates
GCHandle hangupDelegateHandle; // GCHandle to the hangup delegate inputFunction dtmfDelegate;
hangupFunction hangupDelegate;
#else #else
guint32 dtmfDelegateHandle; // GCHandle to the input delegate guint32 dtmfDelegateHandle; // GCHandle to the input delegate
guint32 hangupDelegateHandle; // GCHandle to the hangup delegate guint32 hangupDelegateHandle; // GCHandle to the hangup delegate

View File

@ -47,8 +47,16 @@ namespace FreeSWITCH.Native
/// <summary>Initializes the native ManagedSession. Must be called after Originate.</summary> /// <summary>Initializes the native ManagedSession. Must be called after Originate.</summary>
public void Initialize() public void Initialize()
{ {
// P/Invoke generated function pointers stick around until the delegate is collected
// By sticking the delegates in fields, their lifetime won't be less than the session
// So we don't need to worry about GCHandles and all that....
// Info here: http://blogs.msdn.com/cbrumme/archive/2003/05/06/51385.aspx
this._inputCallbackRef = inputCallback;
this._hangupCallback = hangupCallback;
InitManagedSession(ManagedSession.getCPtr(this).Handle, inputCallback, hangupCallback); InitManagedSession(ManagedSession.getCPtr(this).Handle, inputCallback, hangupCallback);
} }
DtmfCallback _inputCallbackRef;
Action _hangupCallback;
/// <summary>Function to execute when this session hangs up.</summary> /// <summary>Function to execute when this session hangs up.</summary>
public Action HangupFunction { get; set; } public Action HangupFunction { get; set; }

View File

@ -452,8 +452,7 @@ struct dotnet_conf_t {
// Sets up delegates (and anything else needed) on the ManagedSession object // Sets up delegates (and anything else needed) on the ManagedSession object
// Called from ManagedSession.Initialize Managed -> this is Unmanaged code so all pointers are marshalled and prevented from GC // Called from ManagedSession.Initialize Managed -> this is Unmanaged code so all pointers are marshalled and prevented from GC
// Exported method. // Exported method.
SWITCH_MOD_DECLARE(void) InitManagedSession(ManagedSession *session, inputFunction dtmfDelegate, hangupFunction hangupDelegate)
SWITCH_MOD_DECLARE(void) InitManagedSession(ManagedSession *session, void *dtmfDelegate, void *hangupDelegate)
{ {
switch_assert(session); switch_assert(session);
if (!session) { if (!session) {
@ -461,8 +460,8 @@ SWITCH_MOD_DECLARE(void) InitManagedSession(ManagedSession *session, void *dtmfD
} }
session->setDTMFCallback(NULL, ""); session->setDTMFCallback(NULL, "");
session->setHangupHook(NULL); session->setHangupHook(NULL);
session->dtmfDelegateHandle = GCHandle::Alloc(Marshal::GetDelegateForFunctionPointer(IntPtr(dtmfDelegate), InputDelegate::typeid)); session->dtmfDelegate = dtmfDelegate;
session->hangupDelegateHandle = GCHandle::Alloc(Marshal::GetDelegateForFunctionPointer(IntPtr(hangupDelegate), HangupDelegate::typeid)); session->hangupDelegate = hangupDelegate;
} }
switch_status_t loadModDotnetManaged() switch_status_t loadModDotnetManaged()