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
switch_channel_set_private(channel, "CoreSession", NULL);
}
// Free delegates
hangupDelegateHandle.Free();
dtmfDelegateHandle.Free();
}
bool ManagedSession::begin_allow_threads()
@ -91,22 +88,23 @@ bool ManagedSession::end_allow_threads()
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.");
return;
}
((HangupDelegate^)hangupDelegateHandle.Target)();
hangupDelegate();
}
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.");
return SWITCH_STATUS_FALSE;;
}
char *result = ((InputDelegate^)dtmfDelegateHandle.Target)(input, itype);
char *result = dtmfDelegate(input, itype);
switch_status_t status = process_callback_result(result);
Marshal::FreeHGlobal(IntPtr(result)); // I think this is right
return status;
}

View File

@ -99,8 +99,8 @@ using namespace System;
using namespace System::Reflection;
using namespace System::Runtime::InteropServices;
delegate void HangupDelegate(void);
delegate char* InputDelegate(void* input, switch_input_type_t type);
typedef void (*hangupFunction)(void);
typedef char* (*inputFunction)(void*, switch_input_type_t);
public ref class FreeSwitchManaged
{
@ -130,8 +130,9 @@ public:
virtual switch_status_t run_dtmf_callback(void *input, switch_input_type_t itype);
#ifdef _MANAGED
GCHandle dtmfDelegateHandle; // GCHandle to the input delegate
GCHandle hangupDelegateHandle; // GCHandle to the hangup delegate
// P/Invoke function pointer to delegates
inputFunction dtmfDelegate;
hangupFunction hangupDelegate;
#else
guint32 dtmfDelegateHandle; // GCHandle to the input 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>
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);
}
DtmfCallback _inputCallbackRef;
Action _hangupCallback;
/// <summary>Function to execute when this session hangs up.</summary>
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
// Called from ManagedSession.Initialize Managed -> this is Unmanaged code so all pointers are marshalled and prevented from GC
// Exported method.
SWITCH_MOD_DECLARE(void) InitManagedSession(ManagedSession *session, void *dtmfDelegate, void *hangupDelegate)
SWITCH_MOD_DECLARE(void) InitManagedSession(ManagedSession *session, inputFunction dtmfDelegate, hangupFunction hangupDelegate)
{
switch_assert(session);
if (!session) {
@ -461,8 +460,8 @@ SWITCH_MOD_DECLARE(void) InitManagedSession(ManagedSession *session, void *dtmfD
}
session->setDTMFCallback(NULL, "");
session->setHangupHook(NULL);
session->dtmfDelegateHandle = GCHandle::Alloc(Marshal::GetDelegateForFunctionPointer(IntPtr(dtmfDelegate), InputDelegate::typeid));
session->hangupDelegateHandle = GCHandle::Alloc(Marshal::GetDelegateForFunctionPointer(IntPtr(hangupDelegate), HangupDelegate::typeid));
session->dtmfDelegate = dtmfDelegate;
session->hangupDelegate = hangupDelegate;
}
switch_status_t loadModDotnetManaged()