The difference now, is that this actually works

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@9802 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Michael Giagnocavo 2008-10-02 20:02:31 +00:00
parent 40fd65e713
commit 886b02710e
4 changed files with 12 additions and 53 deletions

View File

@ -129,14 +129,6 @@ ManagedSession::~ManagedSession()
{ {
mono_thread_attach(globals.domain); mono_thread_attach(globals.domain);
if (dtmfDelegateHandle) {
mono_gchandle_free(dtmfDelegateHandle);
}
if (hangupDelegateHandle) {
mono_gchandle_free(hangupDelegateHandle);
}
// Do auto-hangup ourselves because CoreSession can't call check_hangup_hook // Do auto-hangup ourselves because CoreSession can't call check_hangup_hook
// after ManagedSession destruction (cause at point it's pure virtual) // after ManagedSession destruction (cause at point it's pure virtual)
if (session) { if (session) {
@ -163,46 +155,19 @@ bool ManagedSession::end_allow_threads()
void ManagedSession::check_hangup_hook() void ManagedSession::check_hangup_hook()
{ {
mono_thread_attach(globals.domain); mono_thread_attach(globals.domain);
if (!hangupDelegateHandle) {
return;
}
MonoObject * hangupDelegate = mono_gchandle_get_target(hangupDelegateHandle);
if (!hangupDelegate) { if (!hangupDelegate) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "hangupDelegateHandle didn't get an object.");
return; return;
} }
hangupDelegate();
MonoObject * ex = NULL;
mono_runtime_delegate_invoke(hangupDelegate, NULL, &ex);
if (ex) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "hangupDelegate threw an exception.");
}
} }
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)
{ {
mono_thread_attach(globals.domain); mono_thread_attach(globals.domain);
if (!dtmfDelegateHandle) {
return SWITCH_STATUS_SUCCESS;
}
MonoObject * dtmfDelegate = mono_gchandle_get_target(dtmfDelegateHandle);
if (!dtmfDelegate) { if (!dtmfDelegate) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "dtmfDelegateHandle didn't get an object.");
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
char *resPtr = dtmfDelegate(input, itype);
void *args[2];
args[0] = &input;
args[1] = &itype;
MonoObject * ex = NULL;
MonoObject * res = mono_runtime_delegate_invoke(dtmfDelegate, args, &ex);
if (ex) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "dtmfDelegate threw an exception.");
return SWITCH_STATUS_FALSE;
}
char *resPtr = mono_string_to_utf8((MonoString *) res);
switch_status_t status = process_callback_result(resPtr); switch_status_t status = process_callback_result(resPtr);
g_free(resPtr); g_free(resPtr);
return status; return status;

View File

@ -38,6 +38,9 @@ SWITCH_BEGIN_EXTERN_C
#include <switch.h> #include <switch.h>
#include <switch_cpp.h> #include <switch_cpp.h>
typedef void (*hangupFunction)(void);
typedef char* (*inputFunction)(void*, switch_input_type_t);
#ifndef _MANAGED #ifndef _MANAGED
// this section remove linker error LNK4248 for these opaque structures // this section remove linker error LNK4248 for these opaque structures
struct switch_core_session {char foo[];}; struct switch_core_session {char foo[];};
@ -99,9 +102,6 @@ using namespace System;
using namespace System::Reflection; using namespace System::Reflection;
using namespace System::Runtime::InteropServices; using namespace System::Runtime::InteropServices;
typedef void (*hangupFunction)(void);
typedef char* (*inputFunction)(void*, switch_input_type_t);
public ref class FreeSwitchManaged public ref class FreeSwitchManaged
{ {
public: public:
@ -129,15 +129,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
// P/Invoke function pointer to delegates // P/Invoke function pointer to delegates
inputFunction dtmfDelegate; inputFunction dtmfDelegate;
hangupFunction hangupDelegate; hangupFunction hangupDelegate;
#else
guint32 dtmfDelegateHandle; // GCHandle to the input delegate
guint32 hangupDelegateHandle; // GCHandle to the hangup delegate
#endif
}; };
#endif #endif

View File

@ -32,16 +32,18 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Runtime.InteropServices;
namespace FreeSWITCH.Native namespace FreeSWITCH.Native
{ {
// 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)
// But, process_callback_result is used to turn a string into a switch_status_t // But, process_callback_result is used to turn a string into a switch_status_t
using DtmfCallback = Func<IntPtr, Native.switch_input_type_t, string>; //using DtmfCallback = Func<IntPtr, Native.switch_input_type_t, string>;
delegate string DtmfCallback(IntPtr input, Native.switch_input_type_t itype);
public partial class ManagedSession public partial class ManagedSession
{ {
// SWITCH_DECLARE(void) InitManagedSession(ManagedSession *session, MonoObject *dtmfDelegate, MonoObject *hangupDelegate) // SWITCH_DECLARE(void) InitManagedSession(ManagedSession *session, MonoObject *dtmfDelegate, MonoObject *hangupDelegate)
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)] [DllImport("mod_managed.dll", CharSet = CharSet.Ansi)]
static extern void InitManagedSession(IntPtr sessionPtr, DtmfCallback dtmfDelegate, Action hangupDelegate); static extern void InitManagedSession(IntPtr sessionPtr, DtmfCallback dtmfDelegate, Action hangupDelegate);
/// <summary>Initializes the native ManagedSession. Must be called after Originate.</summary> /// <summary>Initializes the native ManagedSession. Must be called after Originate.</summary>

View File

@ -80,7 +80,7 @@ mod_mono_globals globals =
// Sets up delegates (and anything else needed) on the ManagedSession object // Sets up delegates (and anything else needed) on the ManagedSession object
// Called via internalcall // Called via internalcall
SWITCH_MOD_DECLARE(void) InitManagedSession(ManagedSession * session, MonoObject * dtmfDelegate, MonoObject * hangupDelegate) SWITCH_MOD_DECLARE(void) InitManagedSession(ManagedSession * session, inputFunction dtmfDelegate, hangupFunction hangupDelegate)
{ {
switch_assert(session); switch_assert(session);
if (!session) { if (!session) {
@ -88,8 +88,8 @@ SWITCH_MOD_DECLARE(void) InitManagedSession(ManagedSession * session, MonoObject
} }
session->setDTMFCallback(NULL, ""); session->setDTMFCallback(NULL, "");
session->setHangupHook(NULL); session->setHangupHook(NULL);
session->dtmfDelegateHandle = mono_gchandle_new(dtmfDelegate, FALSE); session->dtmfDelegate = dtmfDelegate;
session->hangupDelegateHandle = mono_gchandle_new(hangupDelegate, FALSE); session->hangupDelegate = hangupDelegate;
} }
switch_status_t setMonoDirs() switch_status_t setMonoDirs()
@ -283,8 +283,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_managed_load)
/* Not sure if this is necesary on the loading thread */ /* Not sure if this is necesary on the loading thread */
mono_thread_attach(globals.domain); mono_thread_attach(globals.domain);
mono_add_internal_call("FreeSWITCH.Native.ManagedSession::InitManagedSession", (void *)InitManagedSession);
/* Run loader */ /* Run loader */
MonoObject * objResult; MonoObject * objResult;
MonoObject * exception = NULL; MonoObject * exception = NULL;