From 70e390c3e801f008a656b47b50a45e5daa21c736 Mon Sep 17 00:00:00 2001 From: Michael Giagnocavo Date: Thu, 2 Oct 2008 18:10:48 +0000 Subject: [PATCH] First attempt at making CLR delegate stuff work git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@9795 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- .../mod_managed/freeswitch_managed.cpp | 11 ++-- .../mod_managed/freeswitch_managed.h | 14 ++--- src/mod/languages/mod_managed/mod_managed.cpp | 52 ++----------------- .../languages/mod_managed/mod_managed.vcproj | 2 + 4 files changed, 19 insertions(+), 60 deletions(-) diff --git a/src/mod/languages/mod_managed/freeswitch_managed.cpp b/src/mod/languages/mod_managed/freeswitch_managed.cpp index 83c78ab626..119fb3a728 100644 --- a/src/mod/languages/mod_managed/freeswitch_managed.cpp +++ b/src/mod/languages/mod_managed/freeswitch_managed.cpp @@ -74,6 +74,9 @@ 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() @@ -88,20 +91,20 @@ bool ManagedSession::end_allow_threads() void ManagedSession::check_hangup_hook() { - if (!hangupDelegateHandle) { + if (!hangupDelegateHandle.IsAllocated) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "hangupDelegateHandle didn't get an object."); return; } - hangupDelegateHandle(); + ((HangupDelegate^)hangupDelegateHandle.Target)(); } switch_status_t ManagedSession::run_dtmf_callback(void *input, switch_input_type_t itype) { - if (!dtmfDelegateHandle) { + if (!dtmfDelegateHandle.IsAllocated) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "dtmfDelegateHandle didn't get an object."); return SWITCH_STATUS_FALSE;; } - char* result = dtmfDelegateHandle(input, itype); + char *result = ((InputDelegate^)dtmfDelegateHandle.Target)(input, itype); switch_status_t status = process_callback_result(result); return status; diff --git a/src/mod/languages/mod_managed/freeswitch_managed.h b/src/mod/languages/mod_managed/freeswitch_managed.h index 7de5ab4b97..97b6d02fde 100644 --- a/src/mod/languages/mod_managed/freeswitch_managed.h +++ b/src/mod/languages/mod_managed/freeswitch_managed.h @@ -38,7 +38,7 @@ SWITCH_BEGIN_EXTERN_C #include #include -#ifdef _MANAGED +#ifndef _MANAGED // this section remove linker error LNK4248 for these opaque structures struct switch_core_session {char foo[];}; struct apr_pool_t {char foo[];}; @@ -69,11 +69,6 @@ SWITCH_BEGIN_EXTERN_C struct apr_socket_t {char foo[];}; // LNK Error -typedef char* (CALLBACK* inputtype)(void * input, switch_input_type_t type); -typedef void (CALLBACK* hanguptype)(); - -#else - #include #include @@ -104,7 +99,8 @@ using namespace System; using namespace System::Reflection; using namespace System::Runtime::InteropServices; -delegate void HangupMethod(); +delegate void HangupDelegate(void); +delegate char* InputDelegate(void* input, switch_input_type_t type); public ref class FreeSwitchManaged { @@ -134,8 +130,8 @@ public: virtual switch_status_t run_dtmf_callback(void *input, switch_input_type_t itype); #ifdef _MANAGED - inputtype dtmfDelegateHandle; // GCHandle to the input delegate - hanguptype hangupDelegateHandle; // GCHandle to the hangup delegate + GCHandle dtmfDelegateHandle; // GCHandle to the input delegate + GCHandle hangupDelegateHandle; // GCHandle to the hangup delegate #else guint32 dtmfDelegateHandle; // GCHandle to the input delegate guint32 hangupDelegateHandle; // GCHandle to the hangup delegate diff --git a/src/mod/languages/mod_managed/mod_managed.cpp b/src/mod/languages/mod_managed/mod_managed.cpp index 12d0595555..cca9fe7248 100644 --- a/src/mod/languages/mod_managed/mod_managed.cpp +++ b/src/mod/languages/mod_managed/mod_managed.cpp @@ -448,10 +448,12 @@ struct dotnet_conf_t { //char *cor_version; } globals; + // 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, inputtype dtmfDelegate, hanguptype hangupDelegate) + +SWITCH_MOD_DECLARE(void) InitManagedSession(ManagedSession *session, void *dtmfDelegate, void *hangupDelegate) { switch_assert(session); if (!session) { @@ -459,8 +461,8 @@ SWITCH_MOD_DECLARE(void) InitManagedSession(ManagedSession * session, inputtype } session->setDTMFCallback(NULL, ""); session->setHangupHook(NULL); - session->dtmfDelegateHandle = dtmfDelegate; - session->hangupDelegateHandle = hangupDelegate; + session->dtmfDelegateHandle = GCHandle::Alloc(Marshal::GetDelegateForFunctionPointer(IntPtr(dtmfDelegate), InputDelegate::typeid)); + session->hangupDelegateHandle = GCHandle::Alloc(Marshal::GetDelegateForFunctionPointer(IntPtr(hangupDelegate), HangupDelegate::typeid)); } switch_status_t loadModDotnetManaged() @@ -469,50 +471,6 @@ switch_status_t loadModDotnetManaged() char filename[256]; switch_snprintf(filename, 256, "%s%s%s", SWITCH_GLOBAL_dirs.mod_dir, SWITCH_PATH_SEPARATOR, MOD_MANAGED_DLL); - //HRESULT hr; - //wchar_t wCORVersion[256]; - //if (globals.cor_version) { - // MultiByteToWideChar(CP_UTF8, 0, globals.cor_version, -1, - // wCORVersion, sizeof(wCORVersion) / sizeof(wchar_t)); - //} - //else { - // DWORD bytes; - // hr = GetCORVersion(wCORVersion, sizeof(wCORVersion) - // / sizeof(wchar_t) - 1, &bytes); - // if (FAILED(hr)) { - // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - // "mod_dotnet: GetCORVersion failed to return " - // "the .NET CLR engine version."); - // return SWITCH_STATUS_FALSE; - // } - // int len = WideCharToMultiByte(CP_UTF8, 0, wCORVersion, -1, - // NULL, 0, NULL, NULL); - // globals.cor_version = (char *)apr_palloc(globals.pool, len); - // len = WideCharToMultiByte(CP_UTF8, 0, wCORVersion, -1, - // globals.cor_version, len, NULL, NULL); - //} - - ////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 - //hr = CorBindToRuntimeEx(wCORVersion, - // L"wks", // Or "svr" - // STARTUP_LOADER_OPTIMIZATION_MULTI_DOMAIN_HOST | - // STARTUP_CONCURRENT_GC, - // CLSID_CorRuntimeHost, - // IID_ICorRuntimeHost, - // (void **)&globals.pCorRuntime); - //if (FAILED(hr)) { - // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - // "mod_dotnet: Could not CorBindToRuntimeEx version " - // "%s for the .NET CLR engine.", globals.cor_version); - // return SWITCH_STATUS_FALSE; - //} - - //if (FAILED(hr)) { // a value of one here means that the specified clr is already loaded and good. - // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, - // "mod_dotnet: Could not start the " - // ".NET CLR engine."); - // return SWITCH_STATUS_FALSE; - //} wchar_t modpath[256]; mbstowcs(modpath, filename, 255); try { diff --git a/src/mod/languages/mod_managed/mod_managed.vcproj b/src/mod/languages/mod_managed/mod_managed.vcproj index 04c9478119..13218cd8fc 100644 --- a/src/mod/languages/mod_managed/mod_managed.vcproj +++ b/src/mod/languages/mod_managed/mod_managed.vcproj @@ -44,6 +44,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="" + AdditionalUsingDirectories="" PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS" MinimalRebuild="false" BasicRuntimeChecks="0" @@ -127,6 +128,7 @@ Optimization="3" EnableIntrinsicFunctions="true" AdditionalIncludeDirectories="" + AdditionalUsingDirectories="" PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_MONO_EXPORTS" RuntimeLibrary="2" EnableFunctionLevelLinking="true"