#ifdef WIN32\r
#include <shlobj.h>\r
#define EXPORT __declspec(dllexport)\r
-#elif\r
+#else\r
#define EXPORT \r
#endif \r
\r
#define MOD_MONO_MANAGED_DLL "mod_mono_managed.dll"\r
- \r
+\r
+#define MOD_MONO_MANAGED_ASM_NAME "mod_mono_managed"\r
+#define MOD_MONO_MANAGED_ASM_V1 1\r
+#define MOD_MONO_MANAGED_ASM_V2 0\r
+#define MOD_MONO_MANAGED_ASM_V3 0\r
+#define MOD_MONO_MANAGED_ASM_V4 0\r
+\r
mod_mono_globals globals = \r
{ 0 };\r
\r
return SWITCH_STATUS_SUCCESS;\r
}\r
\r
-#elif\r
+#else\r
// On other platforms, it should just work if it hasn't been relocated\r
mono_set_dirs(NULL, NULL);\r
return SWITCH_STATUS_SUCCESS;\r
switch_snprintf(filename, 256, "%s%s%s", SWITCH_GLOBAL_dirs.mod_dir, SWITCH_PATH_SEPARATOR, MOD_MONO_MANAGED_DLL);\r
globals.domain = mono_jit_init(filename);\r
\r
- if (!globals.domain) {\r
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mono_jit_init failed.\n");\r
- return SWITCH_STATUS_FALSE;\r
+ /* Already got a Mono domain? */\r
+ if ((globals.domain = mono_get_root_domain())) {\r
+ mono_thread_attach(globals.domain);\r
+ globals.embedded = SWITCH_TRUE;\r
+ } else {\r
+ if (!(globals.domain = mono_jit_init(filename))) {\r
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mono_jit_init failed.\n");\r
+ return SWITCH_STATUS_FALSE;\r
+ }\r
}\r
\r
- /* Open the assembly */ \r
- globals.mod_mono_asm = mono_domain_assembly_open(globals.domain, filename);\r
-\r
- if (!globals.mod_mono_asm) {\r
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mono_domain_assembly_open failed.\n");\r
- return SWITCH_STATUS_FALSE;\r
+ /* Already loaded? */\r
+ MonoAssemblyName name;\r
+ name.name = MOD_MONO_MANAGED_ASM_NAME;\r
+ name.major = MOD_MONO_MANAGED_ASM_V1;\r
+ name.minor = MOD_MONO_MANAGED_ASM_V2;\r
+ name.revision = MOD_MONO_MANAGED_ASM_V3;\r
+ name.build = MOD_MONO_MANAGED_ASM_V4;\r
+ name.culture = "";\r
+ name.hash_value = "";\r
+\r
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Calling mono_assembly_loaded");\r
+\r
+ if (!(globals.mod_mono_asm = mono_assembly_loaded(&name))) {\r
+ /* Open the assembly */ \r
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Calling mono_domain_assembly_open");\r
+ globals.mod_mono_asm = mono_domain_assembly_open(globals.domain, filename);\r
+ if (!globals.mod_mono_asm) {\r
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mono_domain_assembly_open failed.\n");\r
+ return SWITCH_STATUS_FALSE;\r
+ }\r
}\r
\r
return SWITCH_STATUS_SUCCESS;\r
+\r
}\r
\r
MonoMethod * getMethod(const char *name, MonoClass * klass) \r
/* Not sure if this is necesary on the loading thread */ \r
mono_thread_attach(globals.domain);\r
\r
- mono_add_internal_call("FreeSWITCH.Native.MonoSession::InitMonoSession", InitMonoSession);\r
+ mono_add_internal_call("FreeSWITCH.Native.MonoSession::InitMonoSession", (void *)InitMonoSession);\r
\r
/* Run loader */ \r
MonoObject * objResult;\r
mono_print_unhandled_exception(ex);\r
}\r
\r
- mono_runtime_set_shutting_down();\r
- mono_runtime_cleanup(globals.domain);\r
- mono_runtime_quit();\r
+ if (!globals.embedded) {\r
+ mono_jit_cleanup(globals.domain);\r
+ }\r
\r
return SWITCH_STATUS_SUCCESS;\r
}\r
// we define char as byte.\r
// TODO: Possible? It'd be nice to do the whole char*->IntPtr->Marshal/Free thing here instead of swigStringFix\r
\r
+%typemap(imtype, out="string") char ** "ref string"\r
+%typemap(cstype, out="string") char ** "ref string"\r
+%typemap(csin) char ** "ref $csinput"\r
+%typemap(csvarin) char **\r
+%{\r
+ set { $imcall; }\r
+%}\r
+%typemap(csvarout) char **\r
+%{\r
+ get {\r
+ return $imcall;\r
+ }\r
+%}\r
+\r
#define SWITCH_DECLARE(type) type\r
#define SWITCH_DECLARE_NONSTD(type) type\r
#define SWITCH_MOD_DECLARE(type) type\r
#define _Out_cap_(x)\r
#define _Out_z_cap_(x)\r
#define _Out_ptrdiff_cap_(x)\r
-#define _Out_opt_ptrdiff_cap_(x)
\ No newline at end of file
+#define _Out_opt_ptrdiff_cap_(x)\r
} \r
}\r
\r
- static List<Assembly> loadAssemblies(string managedDir)\r
+ static Assembly[] loadAssemblies(string managedDir)\r
{\r
- return Directory.GetFiles(managedDir, "*.dll", SearchOption.AllDirectories)\r
- .Select(f => Path.Combine(managedDir, f))\r
- .Select(f => {\r
- try {\r
- return System.Reflection.Assembly.LoadFile(f);\r
- }\r
- catch (Exception ex) {\r
- Log.WriteLine(LogLevel.Notice, "Assembly.LoadFile failed; skipping {0} ({1})", f, ex.Message);\r
- return null;\r
- }\r
- })\r
- .Where(a => a != null)\r
- .Concat(new[] { System.Reflection.Assembly.GetExecutingAssembly() }) // Add in our own to load Demo or built-in things if added\r
- .ToList();\r
+ // load the modules in the mod/mono directory\r
+ Log.WriteLine(LogLevel.Notice, "loadAssemblies: {0}", managedDir);\r
+ foreach (string s in Directory.GetFiles(managedDir, "*.dll", SearchOption.AllDirectories))\r
+ {\r
+ string f = Path.Combine(managedDir, s);\r
+ try {\r
+ System.Reflection.Assembly.LoadFile(f);\r
+ }\r
+ catch (Exception ex) {\r
+ Log.WriteLine(LogLevel.Notice, "Assembly.LoadFile failed; skipping {0} ({1})", f, ex.Message);\r
+ }\r
+ }\r
+\r
+ return AppDomain.CurrentDomain.GetAssemblies(); // Includes anything else already loaded\r
}\r
\r
public static void Unload()\r