]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
(MODLANG-83) mod_mono Linux build & embedding
authorMichael Jerris <mike@jerris.com>
Tue, 16 Sep 2008 23:54:23 +0000 (23:54 +0000)
committerMichael Jerris <mike@jerris.com>
Tue, 16 Sep 2008 23:54:23 +0000 (23:54 +0000)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@9576 d0543943-73ff-0310-b7d9-9358b9ac24b2

src/mod/languages/mod_mono/Makefile [new file with mode: 0644]
src/mod/languages/mod_mono/freeswitch.i
src/mod/languages/mod_mono/freeswitch_mono.h
src/mod/languages/mod_mono/mod_mono.cpp
src/mod/languages/mod_mono/runswig.sh [new file with mode: 0644]
src/mod/languages/mod_mono/switch_platform.i
src/mod/languages/mod_mono_managed/Loader.cs
src/mod/languages/mod_mono_managed/Makefile [new file with mode: 0644]

diff --git a/src/mod/languages/mod_mono/Makefile b/src/mod/languages/mod_mono/Makefile
new file mode 100644 (file)
index 0000000..0bae30a
--- /dev/null
@@ -0,0 +1,16 @@
+#MOD_CFLAGS=`pkg-config --cflags --libs mono`\r
+MOD_CFLAGS=-D_REENTRANT -pthread -I/opt/mono-1.9/lib/pkgconfig/../../include/mono-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -lmono\r
+#LDFLAGS=`pkg-config --libs mono`\r
+BASE=../../../..\r
+VERBOSE=1\r
+include $(BASE)/build/modmake.rules\r
+LOCAL_OBJS=freeswitch_mono.o freeswitch_wrap.o\r
+local_depend: $(LOCAL_OBJS)\r
+\r
+freeswitch_mono.o: freeswitch_mono.h freeswitch_mono.cpp\r
+\r
+freeswitch_wrap.o: freeswitch_wrap.cpp\r
+\r
+freeswitch_wrap.cpp: freeswitch_wrap.cxx\r
+       cp freeswitch_wrap.cxx freeswitch_wrap.cpp\r
+\r
index 1d5b917963b44563ba75f9d87aacba4491c0092b..5cb7931a9defdad225f986f0b79f42492649bdb5 100644 (file)
 %ignore switch_core_session_get_event_hooks;\r
 %ignore switch_inet_pton;\r
 %ignore switch_xml_idx;\r
+%ignore switch_xml_pi;\r
 \r
 // Real header includes now\r
 %import switch_platform.i // This will give us all the macros we need to compile the other stuff\r
index 3bc17bc7e1c7b66c04f03c2d1fc93efef8f95409..341ff25a2d23544f97be2f846466f3a5eed9462b 100644 (file)
@@ -44,6 +44,7 @@ struct mod_mono_globals {
        MonoDomain *domain;\r
        MonoAssembly *mod_mono_asm;\r
        switch_memory_pool_t *pool;\r
+       switch_bool_t embedded;\r
 \r
        MonoMethod *loadMethod;\r
        MonoMethod *unloadMethod;\r
@@ -76,4 +77,4 @@ public:
        guint32 hangupDelegateHandle; // GCHandle to the hangup delegate\r
 };\r
 \r
-#endif
\ No newline at end of file
+#endif\r
index e9ed68abc992ccb8df1015810ed09e5d0f41a182..f1c9df101f1bcecf12a38b7752d82ef97f24e4c5 100644 (file)
@@ -47,12 +47,18 @@ SWITCH_BEGIN_EXTERN_C
 #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
@@ -120,7 +126,7 @@ switch_status_t setMonoDirs()
                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
@@ -137,20 +143,41 @@ switch_status_t loadModMonoManaged()
        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
@@ -226,7 +253,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_mono_load)
        /* 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
@@ -360,9 +387,9 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_mono_shutdown)
                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
diff --git a/src/mod/languages/mod_mono/runswig.sh b/src/mod/languages/mod_mono/runswig.sh
new file mode 100644 (file)
index 0000000..86e85a0
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/bash\r
+swig -I../../../include -v -O -c++ -csharp -namespace FreeSWITCH.Native -dllimport mod_mono freeswitch.i\r
+rm -f ../mod_mono_managed/swig.cs\r
+cat *.cs > ../mod_mono_managed/swig.cs\r
+rm -f *.cs\r
index 81e062fae6ee0c7b3d5583f1bb48847f9b5f6093..262acc6c447229c49c05233affaa5cf02c102d2c 100644 (file)
@@ -14,6 +14,20 @@ typedef unsigned long in_addr_t;
 //             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
@@ -42,4 +56,4 @@ typedef unsigned long in_addr_t;
 #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
index a8d254ffe65021cd181d256525ea289802a91dfd..ade3509a94780645c08ca3f95ff315700a85597d 100644 (file)
@@ -100,22 +100,22 @@ namespace FreeSWITCH
             } \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
diff --git a/src/mod/languages/mod_mono_managed/Makefile b/src/mod/languages/mod_mono_managed/Makefile
new file mode 100644 (file)
index 0000000..0fde8fe
--- /dev/null
@@ -0,0 +1,13 @@
+all: Debug Debug/mod_mono_managed.dll\r
+\r
+clean:\r
+       rm -fr Debug\r
+\r
+Debug:\r
+       mkdir Debug\r
+\r
+Debug/mod_mono_managed.dll: Loader.cs MonoSession.cs ApiFunction.cs AppFunction.cs Extensions.cs Log.cs Demo.cs swig.cs\r
+       gmcs -target:library -out:Debug/mod_mono_managed.dll -d:DEBUG Loader.cs MonoSession.cs ApiFunction.cs AppFunction.cs Extensions.cs Log.cs Demo.cs swig.cs\r
+\r
+install: Debug/mod_mono_managed.dll\r
+       install Debug/mod_mono_managed.dll /usr/local/freeswitch/mod\r