[Freeswitch-svn] [commit] r9797 - in freeswitch/trunk/src/mod/languages/mod_managed: . managed

Freeswitch SVN michaelgg at freeswitch.org
Thu Oct 2 14:59:09 EDT 2008


Author: michaelgg
Date: Thu Oct  2 14:59:09 2008
New Revision: 9797

Modified:
   freeswitch/trunk/src/mod/languages/mod_managed/freeswitch_managed.cpp
   freeswitch/trunk/src/mod/languages/mod_managed/freeswitch_managed.h
   freeswitch/trunk/src/mod/languages/mod_managed/managed/ManagedSession.cs
   freeswitch/trunk/src/mod/languages/mod_managed/mod_managed.cpp

Log:
P/Invoke should do all the work for us

Modified: freeswitch/trunk/src/mod/languages/mod_managed/freeswitch_managed.cpp
==============================================================================
--- freeswitch/trunk/src/mod/languages/mod_managed/freeswitch_managed.cpp	(original)
+++ freeswitch/trunk/src/mod/languages/mod_managed/freeswitch_managed.cpp	Thu Oct  2 14:59:09 2008
@@ -74,9 +74,6 @@
 		// 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 @@
 
 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;
 }
 

Modified: freeswitch/trunk/src/mod/languages/mod_managed/freeswitch_managed.h
==============================================================================
--- freeswitch/trunk/src/mod/languages/mod_managed/freeswitch_managed.h	(original)
+++ freeswitch/trunk/src/mod/languages/mod_managed/freeswitch_managed.h	Thu Oct  2 14:59:09 2008
@@ -99,8 +99,8 @@
 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 @@
 	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

Modified: freeswitch/trunk/src/mod/languages/mod_managed/managed/ManagedSession.cs
==============================================================================
--- freeswitch/trunk/src/mod/languages/mod_managed/managed/ManagedSession.cs	(original)
+++ freeswitch/trunk/src/mod/languages/mod_managed/managed/ManagedSession.cs	Thu Oct  2 14:59:09 2008
@@ -47,8 +47,16 @@
         /// <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; }

Modified: freeswitch/trunk/src/mod/languages/mod_managed/mod_managed.cpp
==============================================================================
--- freeswitch/trunk/src/mod/languages/mod_managed/mod_managed.cpp	(original)
+++ freeswitch/trunk/src/mod/languages/mod_managed/mod_managed.cpp	Thu Oct  2 14:59:09 2008
@@ -452,8 +452,7 @@
 // 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 @@
 	}
 	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() 



More information about the Freeswitch-svn mailing list