(MODLANG-83) mod_mono Linux build & embedding

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@9576 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Michael Jerris 2008-09-16 23:54:23 +00:00
parent 260ebb8338
commit 19811e4f08
8 changed files with 109 additions and 32 deletions

View File

@ -0,0 +1,16 @@
#MOD_CFLAGS=`pkg-config --cflags --libs mono`
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
#LDFLAGS=`pkg-config --libs mono`
BASE=../../../..
VERBOSE=1
include $(BASE)/build/modmake.rules
LOCAL_OBJS=freeswitch_mono.o freeswitch_wrap.o
local_depend: $(LOCAL_OBJS)
freeswitch_mono.o: freeswitch_mono.h freeswitch_mono.cpp
freeswitch_wrap.o: freeswitch_wrap.cpp
freeswitch_wrap.cpp: freeswitch_wrap.cxx
cp freeswitch_wrap.cxx freeswitch_wrap.cpp

View File

@ -107,6 +107,7 @@
%ignore switch_core_session_get_event_hooks;
%ignore switch_inet_pton;
%ignore switch_xml_idx;
%ignore switch_xml_pi;
// Real header includes now
%import switch_platform.i // This will give us all the macros we need to compile the other stuff

View File

@ -44,6 +44,7 @@ struct mod_mono_globals {
MonoDomain *domain;
MonoAssembly *mod_mono_asm;
switch_memory_pool_t *pool;
switch_bool_t embedded;
MonoMethod *loadMethod;
MonoMethod *unloadMethod;
@ -76,4 +77,4 @@ public:
guint32 hangupDelegateHandle; // GCHandle to the hangup delegate
};
#endif
#endif

View File

@ -47,12 +47,18 @@ SWITCH_BEGIN_EXTERN_C
#ifdef WIN32
#include <shlobj.h>
#define EXPORT __declspec(dllexport)
#elif
#else
#define EXPORT
#endif
#define MOD_MONO_MANAGED_DLL "mod_mono_managed.dll"
#define MOD_MONO_MANAGED_ASM_NAME "mod_mono_managed"
#define MOD_MONO_MANAGED_ASM_V1 1
#define MOD_MONO_MANAGED_ASM_V2 0
#define MOD_MONO_MANAGED_ASM_V3 0
#define MOD_MONO_MANAGED_ASM_V4 0
mod_mono_globals globals =
{ 0 };
@ -120,7 +126,7 @@ switch_status_t setMonoDirs()
return SWITCH_STATUS_SUCCESS;
}
#elif
#else
// On other platforms, it should just work if it hasn't been relocated
mono_set_dirs(NULL, NULL);
return SWITCH_STATUS_SUCCESS;
@ -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);
globals.domain = mono_jit_init(filename);
if (!globals.domain) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mono_jit_init failed.\n");
return SWITCH_STATUS_FALSE;
/* Already got a Mono domain? */
if ((globals.domain = mono_get_root_domain())) {
mono_thread_attach(globals.domain);
globals.embedded = SWITCH_TRUE;
} else {
if (!(globals.domain = mono_jit_init(filename))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mono_jit_init failed.\n");
return SWITCH_STATUS_FALSE;
}
}
/* Open the assembly */
globals.mod_mono_asm = mono_domain_assembly_open(globals.domain, filename);
/* Already loaded? */
MonoAssemblyName name;
name.name = MOD_MONO_MANAGED_ASM_NAME;
name.major = MOD_MONO_MANAGED_ASM_V1;
name.minor = MOD_MONO_MANAGED_ASM_V2;
name.revision = MOD_MONO_MANAGED_ASM_V3;
name.build = MOD_MONO_MANAGED_ASM_V4;
name.culture = "";
name.hash_value = "";
if (!globals.mod_mono_asm) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mono_domain_assembly_open failed.\n");
return SWITCH_STATUS_FALSE;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Calling mono_assembly_loaded");
if (!(globals.mod_mono_asm = mono_assembly_loaded(&name))) {
/* Open the assembly */
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Calling mono_domain_assembly_open");
globals.mod_mono_asm = mono_domain_assembly_open(globals.domain, filename);
if (!globals.mod_mono_asm) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "mono_domain_assembly_open failed.\n");
return SWITCH_STATUS_FALSE;
}
}
return SWITCH_STATUS_SUCCESS;
}
MonoMethod * getMethod(const char *name, MonoClass * klass)
@ -226,7 +253,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_mono_load)
/* Not sure if this is necesary on the loading thread */
mono_thread_attach(globals.domain);
mono_add_internal_call("FreeSWITCH.Native.MonoSession::InitMonoSession", InitMonoSession);
mono_add_internal_call("FreeSWITCH.Native.MonoSession::InitMonoSession", (void *)InitMonoSession);
/* Run loader */
MonoObject * objResult;
@ -360,9 +387,9 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_mono_shutdown)
mono_print_unhandled_exception(ex);
}
mono_runtime_set_shutting_down();
mono_runtime_cleanup(globals.domain);
mono_runtime_quit();
if (!globals.embedded) {
mono_jit_cleanup(globals.domain);
}
return SWITCH_STATUS_SUCCESS;
}

View File

@ -0,0 +1,5 @@
#!/bin/bash
swig -I../../../include -v -O -c++ -csharp -namespace FreeSWITCH.Native -dllimport mod_mono freeswitch.i
rm -f ../mod_mono_managed/swig.cs
cat *.cs > ../mod_mono_managed/swig.cs
rm -f *.cs

View File

@ -14,6 +14,20 @@ typedef unsigned long in_addr_t;
// we define char as byte.
// TODO: Possible? It'd be nice to do the whole char*->IntPtr->Marshal/Free thing here instead of swigStringFix
%typemap(imtype, out="string") char ** "ref string"
%typemap(cstype, out="string") char ** "ref string"
%typemap(csin) char ** "ref $csinput"
%typemap(csvarin) char **
%{
set { $imcall; }
%}
%typemap(csvarout) char **
%{
get {
return $imcall;
}
%}
#define SWITCH_DECLARE(type) type
#define SWITCH_DECLARE_NONSTD(type) type
#define SWITCH_MOD_DECLARE(type) type
@ -42,4 +56,4 @@ typedef unsigned long in_addr_t;
#define _Out_cap_(x)
#define _Out_z_cap_(x)
#define _Out_ptrdiff_cap_(x)
#define _Out_opt_ptrdiff_cap_(x)
#define _Out_opt_ptrdiff_cap_(x)

View File

@ -100,22 +100,22 @@ namespace FreeSWITCH
}
}
static List<Assembly> loadAssemblies(string managedDir)
static Assembly[] loadAssemblies(string managedDir)
{
return Directory.GetFiles(managedDir, "*.dll", SearchOption.AllDirectories)
.Select(f => Path.Combine(managedDir, f))
.Select(f => {
try {
return System.Reflection.Assembly.LoadFile(f);
}
catch (Exception ex) {
Log.WriteLine(LogLevel.Notice, "Assembly.LoadFile failed; skipping {0} ({1})", f, ex.Message);
return null;
}
})
.Where(a => a != null)
.Concat(new[] { System.Reflection.Assembly.GetExecutingAssembly() }) // Add in our own to load Demo or built-in things if added
.ToList();
// load the modules in the mod/mono directory
Log.WriteLine(LogLevel.Notice, "loadAssemblies: {0}", managedDir);
foreach (string s in Directory.GetFiles(managedDir, "*.dll", SearchOption.AllDirectories))
{
string f = Path.Combine(managedDir, s);
try {
System.Reflection.Assembly.LoadFile(f);
}
catch (Exception ex) {
Log.WriteLine(LogLevel.Notice, "Assembly.LoadFile failed; skipping {0} ({1})", f, ex.Message);
}
}
return AppDomain.CurrentDomain.GetAssemblies(); // Includes anything else already loaded
}
public static void Unload()

View File

@ -0,0 +1,13 @@
all: Debug Debug/mod_mono_managed.dll
clean:
rm -fr Debug
Debug:
mkdir Debug
Debug/mod_mono_managed.dll: Loader.cs MonoSession.cs ApiFunction.cs AppFunction.cs Extensions.cs Log.cs Demo.cs swig.cs
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
install: Debug/mod_mono_managed.dll
install Debug/mod_mono_managed.dll /usr/local/freeswitch/mod