// Don't let any callbacks use this CoreSession anymore\r
switch_channel_set_private(channel, "CoreSession", NULL);\r
}\r
+ // Free delegates\r
+ hangupDelegateHandle.Free();\r
+ dtmfDelegateHandle.Free();\r
}\r
\r
bool ManagedSession::begin_allow_threads() \r
\r
void ManagedSession::check_hangup_hook() \r
{\r
- if (!hangupDelegateHandle) {\r
+ if (!hangupDelegateHandle.IsAllocated) {\r
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "hangupDelegateHandle didn't get an object.");\r
return;\r
}\r
- hangupDelegateHandle();\r
+ ((HangupDelegate^)hangupDelegateHandle.Target)();\r
}\r
\r
switch_status_t ManagedSession::run_dtmf_callback(void *input, switch_input_type_t itype) \r
{\r
- if (!dtmfDelegateHandle) {\r
+ if (!dtmfDelegateHandle.IsAllocated) {\r
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "dtmfDelegateHandle didn't get an object.");\r
return SWITCH_STATUS_FALSE;;\r
}\r
- char* result = dtmfDelegateHandle(input, itype);\r
+ char *result = ((InputDelegate^)dtmfDelegateHandle.Target)(input, itype);\r
\r
switch_status_t status = process_callback_result(result);\r
return status;\r
#include <switch.h>\r
#include <switch_cpp.h>\r
\r
-#ifdef _MANAGED\r
+#ifndef _MANAGED\r
// this section remove linker error LNK4248 for these opaque structures\r
struct switch_core_session {char foo[];};\r
struct apr_pool_t {char foo[];};\r
struct apr_socket_t {char foo[];};\r
// LNK Error\r
\r
-typedef char* (CALLBACK* inputtype)(void * input, switch_input_type_t type);\r
-typedef void (CALLBACK* hanguptype)();\r
-\r
-#else\r
-\r
#include <mono/jit/jit.h>\r
#include <mono/metadata/assembly.h>\r
\r
using namespace System::Reflection;\r
using namespace System::Runtime::InteropServices;\r
\r
-delegate void HangupMethod();\r
+delegate void HangupDelegate(void);\r
+delegate char* InputDelegate(void* input, switch_input_type_t type);\r
\r
public ref class FreeSwitchManaged\r
{\r
virtual switch_status_t run_dtmf_callback(void *input, switch_input_type_t itype);\r
\r
#ifdef _MANAGED\r
- inputtype dtmfDelegateHandle; // GCHandle to the input delegate \r
- hanguptype hangupDelegateHandle; // GCHandle to the hangup delegate\r
+ GCHandle dtmfDelegateHandle; // GCHandle to the input delegate \r
+ GCHandle hangupDelegateHandle; // GCHandle to the hangup delegate\r
#else\r
guint32 dtmfDelegateHandle; // GCHandle to the input delegate \r
guint32 hangupDelegateHandle; // GCHandle to the hangup delegate\r
//char *cor_version;\r
} globals;\r
\r
+\r
// Sets up delegates (and anything else needed) on the ManagedSession object\r
// Called from ManagedSession.Initialize Managed -> this is Unmanaged code so all pointers are marshalled and prevented from GC\r
// Exported method.\r
-SWITCH_MOD_DECLARE(void) InitManagedSession(ManagedSession * session, inputtype dtmfDelegate, hanguptype hangupDelegate) \r
+\r
+SWITCH_MOD_DECLARE(void) InitManagedSession(ManagedSession *session, void *dtmfDelegate, void *hangupDelegate) \r
{\r
switch_assert(session);\r
if (!session) {\r
}\r
session->setDTMFCallback(NULL, "");\r
session->setHangupHook(NULL);\r
- session->dtmfDelegateHandle = dtmfDelegate;\r
- session->hangupDelegateHandle = hangupDelegate;\r
+ session->dtmfDelegateHandle = GCHandle::Alloc(Marshal::GetDelegateForFunctionPointer(IntPtr(dtmfDelegate), InputDelegate::typeid));\r
+ session->hangupDelegateHandle = GCHandle::Alloc(Marshal::GetDelegateForFunctionPointer(IntPtr(hangupDelegate), HangupDelegate::typeid));\r
}\r
\r
switch_status_t loadModDotnetManaged() \r
char filename[256];\r
switch_snprintf(filename, 256, "%s%s%s", SWITCH_GLOBAL_dirs.mod_dir, SWITCH_PATH_SEPARATOR, MOD_MANAGED_DLL);\r
\r
- //HRESULT hr;\r
- //wchar_t wCORVersion[256];\r
- //if (globals.cor_version) {\r
- // MultiByteToWideChar(CP_UTF8, 0, globals.cor_version, -1,\r
- // wCORVersion, sizeof(wCORVersion) / sizeof(wchar_t));\r
- //}\r
- //else {\r
- // DWORD bytes;\r
- // hr = GetCORVersion(wCORVersion, sizeof(wCORVersion) \r
- // / sizeof(wchar_t) - 1, &bytes);\r
- // if (FAILED(hr)) {\r
- // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, \r
- // "mod_dotnet: GetCORVersion failed to return "\r
- // "the .NET CLR engine version.");\r
- // return SWITCH_STATUS_FALSE;\r
- // }\r
- // int len = WideCharToMultiByte(CP_UTF8, 0, wCORVersion, -1, \r
- // NULL, 0, NULL, NULL);\r
- // globals.cor_version = (char *)apr_palloc(globals.pool, len);\r
- // len = WideCharToMultiByte(CP_UTF8, 0, wCORVersion, -1, \r
- // globals.cor_version, len, NULL, NULL);\r
- //}\r
-\r
- ////verify that the clr is already loaded - because this dll is a clr enabled dll it will be loaded but lets get its info anyway\r
- //hr = CorBindToRuntimeEx(wCORVersion, \r
- // L"wks", // Or "svr" \r
- // STARTUP_LOADER_OPTIMIZATION_MULTI_DOMAIN_HOST | \r
- // STARTUP_CONCURRENT_GC, \r
- // CLSID_CorRuntimeHost, \r
- // IID_ICorRuntimeHost, \r
- // (void **)&globals.pCorRuntime);\r
- //if (FAILED(hr)) {\r
- // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, \r
- // "mod_dotnet: Could not CorBindToRuntimeEx version "\r
- // "%s for the .NET CLR engine.", globals.cor_version);\r
- // return SWITCH_STATUS_FALSE;\r
- //}\r
-\r
- //if (FAILED(hr)) { // a value of one here means that the specified clr is already loaded and good.\r
- // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,\r
- // "mod_dotnet: Could not start the "\r
- // ".NET CLR engine.");\r
- // return SWITCH_STATUS_FALSE;\r
- //}\r
wchar_t modpath[256];\r
mbstowcs(modpath, filename, 255);\r
try {\r