提交 20a2aee4 authored 作者: Michael Giagnocavo's avatar Michael Giagnocavo

New mod_managed with multi-appdomain (reloading) and scripting support

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@14364 d0543943-73ff-0310-b7d9-9358b9ac24b2
上级 e0fbc0c3
...@@ -34,7 +34,7 @@ swigclean: clean ...@@ -34,7 +34,7 @@ swigclean: clean
rm -f freeswitch_wrap.cxx freeswitch_wrap.cpp managed/swig.cs rm -f freeswitch_wrap.cxx freeswitch_wrap.cpp managed/swig.cs
freeswitch_wrap.cxx: freeswitch_wrap.cxx:
swig -I../../../include -v -O -c++ -csharp -namespace FreeSWITCH.Native -dllimport mod_managed freeswitch.i swig -I../../../include -v -O -c++ -csharp -namespace FreeSWITCH.Native -dllimport mod_managed -DSWIG_CSHARP_NO_STRING_HELPER freeswitch.i
rm -f ./managed/swig.cs rm -f ./managed/swig.cs
cat *.cs > ./managed/swig.cs cat *.cs > ./managed/swig.cs
rm -f *.cs rm -f *.cs
......
%module freeswitch %module freeswitch
/** String fix - copied from csharphead.swg with fix for multiple appdomains **/
/* Must pass -DSWIG_CSHARP_NO_STRING_HELPER to swig */
#if defined(SWIG_CSHARP_NO_STRING_HELPER)
%insert(runtime) %{
/* Callback for returning strings to C# without leaking memory */
#ifndef _MANAGED
#include <glib.h>
#include <mono/jit/jit.h>
#include <mono/metadata/environment.h>
#include <mono/metadata/mono-config.h>
#include <mono/metadata/threads.h>
#include <mono/metadata/debug-helpers.h>
#endif
typedef char * (SWIGSTDCALL* SWIG_CSharpStringHelperCallback)(const char *);
static SWIG_CSharpStringHelperCallback SWIG_csharp_string_callback_real = NULL;
%}
%pragma(csharp) imclasscode=%{
protected class SWIGStringHelper {
public delegate string SWIGStringDelegate(string message);
static SWIGStringDelegate stringDelegate = new SWIGStringDelegate(CreateString);
[DllImport("$dllimport", EntryPoint="SWIGRegisterStringCallback_$module")]
public static extern void SWIGRegisterStringCallback_$module(SWIGStringDelegate stringDelegate);
static string CreateString(string cString) {
return cString;
}
static SWIGStringHelper() {
SWIGRegisterStringCallback_$module(stringDelegate);
}
}
static protected SWIGStringHelper swigStringHelper = new SWIGStringHelper();
%}
%insert(runtime) %{
#ifdef __cplusplus
extern "C"
#endif
SWIGEXPORT void SWIGSTDCALL SWIGRegisterStringCallback_freeswitch(SWIG_CSharpStringHelperCallback callback) {
/* Set this only once, in the main appdomain */
if (SWIG_csharp_string_callback_real == NULL) SWIG_csharp_string_callback_real = callback;
}
char * SWIG_csharp_string_callback(const char * str) {
#ifndef _MANAGED
// Mono won't transition appdomains properly after the callback, so we force it
MonoDomain* dom = mono_domain_get();
char* res = SWIG_csharp_string_callback_real(str);
mono_domain_set(dom, true);
return res;
#else
return SWIG_csharp_string_callback_real(str);
#endif
}
%}
#endif // SWIG_CSHARP_NO_STRING_HELPER
/** insert the following includes into generated code so it compiles */ /** insert the following includes into generated code so it compiles */
%{ %{
#include "switch.h" #include "switch.h"
...@@ -109,6 +174,9 @@ ...@@ -109,6 +174,9 @@
%ignore switch_xml_idx; %ignore switch_xml_idx;
%ignore switch_xml_pi; %ignore switch_xml_pi;
// GCC complains "ISO C++ forbids assignment of arrays"
%ignore switch_vmprintf;
// Real header includes now // Real header includes now
%import switch_platform.i // This will give us all the macros we need to compile the other stuff %import switch_platform.i // This will give us all the macros we need to compile the other stuff
...@@ -136,6 +204,5 @@ ...@@ -136,6 +204,5 @@
%include switch_core_event_hook.h %include switch_core_event_hook.h
%include switch_scheduler.h %include switch_scheduler.h
%include switch_config.h %include switch_config.h
%include switch_cpp.h %include switch_cpp.h
%include freeswitch_managed.h %include freeswitch_managed.h
...@@ -32,5 +32,5 @@ using System.Runtime.InteropServices; ...@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.2.0")] [assembly: AssemblyVersion("1.0.4.0")]
[assembly: AssemblyFileVersion("1.0.2.0")] [assembly: AssemblyFileVersion("1.0.4.0")]
/* /*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_cli * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_managed
* Copyright (C) 2008, Michael Giagnocavo <mgg@packetrino.com> * Copyright (C) 2008, Michael Giagnocavo <mgg@giagnocavo.net>
* *
* Version: MPL 1.1 * Version: MPL 1.1
* *
...@@ -14,73 +14,97 @@ ...@@ -14,73 +14,97 @@
* for the specific language governing rights and limitations under the * for the specific language governing rights and limitations under the
* License. * License.
* *
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_cli * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_managed
* *
* The Initial Developer of the Original Code is * The Initial Developer of the Original Code is
* Michael Giagnocavo <mgg@packetrino.com> * Michael Giagnocavo <mgg@giagnocavo.net>
* Portions created by the Initial Developer are Copyright (C) * Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved. * the Initial Developer. All Rights Reserved.
* *
* Contributor(s): * Contributor(s):
* *
* Michael Giagnocavo <mgg@packetrino.com> * Michael Giagnocavo <mgg@giagnocavo.net>
* *
* Demo.cs -- mod_mono demo classes * Demo.cs -- mod_mono demo classes
* *
*/ */
#if DEBUG // How to test the demo (in the mod/managed directory):
// -- Compile to dll for "normal" loading
// -- Compile to exe for script EXE loading
// -- Rename to demo.csx for dynamic compilation
using System; using System;
using System.Collections.Generic; using FreeSWITCH;
using System.Linq; using FreeSWITCH.Native;
using System.Text;
namespace FreeSWITCH.Demo {
public class AppDemo : AppFunction {
new protected static bool Load() {
Log.WriteLine(LogLevel.Info, "Inside AppDemo::Load.");
return true;
}
protected override void Run() { public class AppDemo : IAppPlugin {
Session.Answer();
Session.DtmfReceivedFunction = (d, t) => {
Log.WriteLine(LogLevel.Info, "Received {0} for {1}.", d, t);
return "";
};
Log.WriteLine(LogLevel.Info, "Inside AppDemo.Run (args '{0}'); HookState is {1}. Now will collect digits.", Arguments, Session.HookState);
Session.CollectDigits(5000); // Hanging up here will cause an abort and the next line won't be written
Log.WriteLine(LogLevel.Info, "AppDemo is finishing its run and will now hang up.");
Session.Hangup("USER_BUSY");
}
void hangupHook() { ManagedSession Session;
Log.WriteLine(LogLevel.Debug, "AppDemo hanging up, UUID: {0}.", this.Uuid); public void Run(AppContext context) {
} Session = context.Session;
Session.HangupFunction = hangupHook;
Session.Answer();
Session.DtmfReceivedFunction = (d, t) => {
Log.WriteLine(LogLevel.Notice, "Received {0} for {1}.", d, t);
return "";
};
Log.WriteLine(LogLevel.Notice, "Inside AppDemo.Run (args '{0}'); HookState is {1}. Now will collect digits.", context.Arguments, Session.HookState);
Session.CollectDigits(5000); // Hanging up here will cause an abort and the next line won't be written
Log.WriteLine(LogLevel.Notice, "AppDemo is finishing its run and will now hang up.");
Session.Hangup("USER_BUSY");
}
protected override bool AbortOnHangup { get { return true; } } void hangupHook() {
Log.WriteLine(LogLevel.Notice, "AppDemo hanging up, UUID: {0}.", this.Session.Uuid);
} }
public class ApiDemo : ApiFunction { }
new protected static bool Load() {
Log.WriteLine(LogLevel.Debug, "Inside ApiDemo::Load.");
return true;
}
public override void ExecuteBackground(string args) { public class ApiDemo : IApiPlugin {
Log.WriteLine(LogLevel.Debug, "ApiDemo on a background thread #({0}), with args '{1}'.",
System.Threading.Thread.CurrentThread.ManagedThreadId, public void Execute(ApiContext context) {
args); context.Stream.Write(string.Format("ApiDemo executed with args '{0}' and event type {1}.",
} context.Arguments, context.Event == null ? "<none>" : context.Event.GetEventType()));
}
public void ExecuteBackground(ApiBackgroundContext context) {
Log.WriteLine(LogLevel.Notice, "ApiDemo on a background thread #({0}), with args '{1}'.",
System.Threading.Thread.CurrentThread.ManagedThreadId,
context.Arguments);
}
}
public class LoadDemo : ILoadNotificationPlugin {
public bool Load() {
Log.WriteLine(LogLevel.Notice, "LoadDemo running.");
return true;
}
}
public class ScriptDemo {
public override void Execute(Native.Stream stream, Native.Event evt, string args) { static void Main() {
stream.Write(string.Format("ApiDemo executed with args '{0}' and event type {1}.", switch (FreeSWITCH.Script.ContextType) {
args, evt == null ? "<none>" : evt.GetEventType())); case ScriptContextType.Api: {
var ctx = FreeSWITCH.Script.GetApiContext();
ctx.Stream.Write("Script executing as API with args: " + ctx.Arguments);
break;
}
case ScriptContextType.ApiBackground: {
var ctx = FreeSWITCH.Script.GetApiBackgroundContext();
Log.WriteLine(LogLevel.Notice, "Executing as APIBackground with args: " + ctx.Arguments);
break;
}
case ScriptContextType.App: {
var ctx = FreeSWITCH.Script.GetAppContext();
Log.WriteLine(LogLevel.Notice, "Executing as App with args: " + ctx.Arguments);
break;
}
} }
} }
} }
#endif
\ No newline at end of file
/* /*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_cli * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_managed
* Copyright (C) 2008, Michael Giagnocavo <mgg@packetrino.com> * Copyright (C) 2008, Michael Giagnocavo <mgg@giagnocavo.net>
* *
* Version: MPL 1.1 * Version: MPL 1.1
* *
...@@ -14,16 +14,16 @@ ...@@ -14,16 +14,16 @@
* for the specific language governing rights and limitations under the * for the specific language governing rights and limitations under the
* License. * License.
* *
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_cli * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_managed
* *
* The Initial Developer of the Original Code is * The Initial Developer of the Original Code is
* Michael Giagnocavo <mgg@packetrino.com> * Michael Giagnocavo <mgg@giagnocavo.net>
* Portions created by the Initial Developer are Copyright (C) * Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved. * the Initial Developer. All Rights Reserved.
* *
* Contributor(s): * Contributor(s):
* *
* Michael Giagnocavo <mgg@packetrino.com> * Michael Giagnocavo <mgg@giagnocavo.net>
* *
* Extensions.cs -- Helper extensions * Extensions.cs -- Helper extensions
* *
......
...@@ -52,9 +52,10 @@ ...@@ -52,9 +52,10 @@
<Compile Include="Loader.cs" /> <Compile Include="Loader.cs" />
<Compile Include="Extensions.cs" /> <Compile Include="Extensions.cs" />
<Compile Include="Log.cs" /> <Compile Include="Log.cs" />
<Compile Include="ApiFunction.cs" /> <None Include="Demo.cs" />
<Compile Include="AppFunction.cs" /> <Compile Include="PluginInterfaces.cs" />
<Compile Include="Demo.cs" /> <Compile Include="PluginManager.cs" />
<Compile Include="ScriptPluginManager.cs" />
<Compile Include="swig.cs" /> <Compile Include="swig.cs" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
......
/* /*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_cli * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_managed
* Copyright (C) 2008, Michael Giagnocavo <mgg@packetrino.com> * Copyright (C) 2008, Michael Giagnocavo <mgg@giagnocavo.net>
* *
* Version: MPL 1.1 * Version: MPL 1.1
* *
...@@ -14,16 +14,16 @@ ...@@ -14,16 +14,16 @@
* for the specific language governing rights and limitations under the * for the specific language governing rights and limitations under the
* License. * License.
* *
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_cli * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_managed
* *
* The Initial Developer of the Original Code is * The Initial Developer of the Original Code is
* Michael Giagnocavo <mgg@packetrino.com> * Michael Giagnocavo <mgg@giagnocavo.net>
* Portions created by the Initial Developer are Copyright (C) * Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved. * the Initial Developer. All Rights Reserved.
* *
* Contributor(s): * Contributor(s):
* *
* Michael Giagnocavo <mgg@packetrino.com> * Michael Giagnocavo <mgg@giagnocavo.net>
* *
* Log.cs -- Log wrappers * Log.cs -- Log wrappers
* *
......
...@@ -3,8 +3,8 @@ all: FreeSWITCH.Managed.dll ...@@ -3,8 +3,8 @@ all: FreeSWITCH.Managed.dll
clean: clean:
rm -fr FreeSWITCH.Managed.dll rm -fr FreeSWITCH.Managed.dll
FreeSWITCH.Managed.dll: Loader.cs ManagedSession.cs ApiFunction.cs AppFunction.cs Extensions.cs Log.cs Demo.cs swig.cs FreeSWITCH.Managed.dll: AssemblyInfo.cs Extensions.cs Loader.cs Log.cs ManagedSession.cs PluginInterfaces.cs PluginManager.cs ScriptPluginManager.cs swig.cs
gmcs -target:library -out:FreeSWITCH.Managed.dll -d:DEBUG Loader.cs ManagedSession.cs ApiFunction.cs AppFunction.cs Extensions.cs Log.cs Demo.cs swig.cs gmcs -target:library -out:FreeSWITCH.Managed.dll AssemblyInfo.cs Extensions.cs Loader.cs Log.cs ManagedSession.cs PluginInterfaces.cs PluginManager.cs ScriptPluginManager.cs swig.cs
install: FreeSWITCH.Managed.dll install: FreeSWITCH.Managed.dll
$(INSTALL) FreeSWITCH.Managed.dll $(DESTDIR)$(MODINSTDIR) $(INSTALL) FreeSWITCH.Managed.dll $(DESTDIR)$(MODINSTDIR)
......
/* /*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_cli * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_managed
* Copyright (C) 2008, Michael Giagnocavo <mgg@packetrino.com> * Copyright (C) 2008, Michael Giagnocavo <mgg@giagnocavo.net>
* *
* Version: MPL 1.1 * Version: MPL 1.1
* *
...@@ -14,16 +14,16 @@ ...@@ -14,16 +14,16 @@
* for the specific language governing rights and limitations under the * for the specific language governing rights and limitations under the
* License. * License.
* *
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_cli * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application - mod_managed
* *
* The Initial Developer of the Original Code is * The Initial Developer of the Original Code is
* Michael Giagnocavo <mgg@packetrino.com> * Michael Giagnocavo <mgg@giagnocavo.net>
* Portions created by the Initial Developer are Copyright (C) * Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved. * the Initial Developer. All Rights Reserved.
* *
* Contributor(s): * Contributor(s):
* *
* Michael Giagnocavo <mgg@packetrino.com> * Michael Giagnocavo <mgg@giagnocavo.net>
* *
* ManagedSession.cs -- ManagedSession additional functions * ManagedSession.cs -- ManagedSession additional functions
* *
...@@ -66,14 +66,10 @@ namespace FreeSWITCH.Native ...@@ -66,14 +66,10 @@ namespace FreeSWITCH.Native
/// <summary>Function to execute when this session hangs up.</summary> /// <summary>Function to execute when this session hangs up.</summary>
public Action HangupFunction { get; set; } public Action HangupFunction { get; set; }
/// <summary>Sets the application that should have it's run thread aborted (if enabled) when this session is hungup.</summary>
internal AppFunction AppToAbort { get; set; }
void hangupCallback() void hangupCallback()
{ {
Log.WriteLine(LogLevel.Debug, "AppFunction is in hangupCallback."); Log.WriteLine(LogLevel.Debug, "AppFunction is in hangupCallback.");
try { try {
if (AppToAbort != null) AppToAbort.AbortRun();
var f = HangupFunction; var f = HangupFunction;
if (f != null) f(); if (f != null) f();
} }
...@@ -121,5 +117,21 @@ namespace FreeSWITCH.Native ...@@ -121,5 +117,21 @@ namespace FreeSWITCH.Native
} }
} }
// Convenience
public bool IsAvailable {
get { return this.Ready(); }
}
Guid _uuid;
bool _uuidSet;
public Guid Uuid {
get {
if (!_uuidSet) {
_uuid = new Guid(this.GetUuid());
_uuidSet = true;
}
return _uuid;
}
}
} }
} }
...@@ -54,7 +54,7 @@ SWITCH_MODULE_DEFINITION_EX(mod_managed, mod_managed_load, NULL, NULL, SMODF_GLO ...@@ -54,7 +54,7 @@ SWITCH_MODULE_DEFINITION_EX(mod_managed, mod_managed_load, NULL, NULL, SMODF_GLO
SWITCH_STANDARD_API(managedrun_api_function); /* ExecuteBackground */ SWITCH_STANDARD_API(managedrun_api_function); /* ExecuteBackground */
SWITCH_STANDARD_API(managed_api_function); /* Execute */ SWITCH_STANDARD_API(managed_api_function); /* Execute */
SWITCH_STANDARD_APP(managed_app_function); /* Run */ SWITCH_STANDARD_APP(managed_app_function); /* Run */
SWITCH_STANDARD_API(managed_loadassembly); /* Load assembly */ SWITCH_STANDARD_API(managedreload_api_function); /* Reload */
#define MOD_MANAGED_ASM_NAME "FreeSWITCH.Managed" #define MOD_MANAGED_ASM_NAME "FreeSWITCH.Managed"
#define MOD_MANAGED_ASM_V1 1 #define MOD_MANAGED_ASM_V1 1
...@@ -71,18 +71,18 @@ mod_managed_globals globals = { 0 }; ...@@ -71,18 +71,18 @@ mod_managed_globals globals = { 0 };
typedef int (*runFunction)(const char *data, void *sessionPtr); typedef int (*runFunction)(const char *data, void *sessionPtr);
typedef int (*executeFunction)(const char *cmd, void *stream, void *Event); typedef int (*executeFunction)(const char *cmd, void *stream, void *Event);
typedef int (*executeBackgroundFunction)(const char* cmd); typedef int (*executeBackgroundFunction)(const char* cmd);
typedef int (*loadAssemblyFunction)(const char* filename); typedef int (*reloadFunction)(const char* cmd);
static runFunction runDelegate; static runFunction runDelegate;
static executeFunction executeDelegate; static executeFunction executeDelegate;
static executeBackgroundFunction executeBackgroundDelegate; static executeBackgroundFunction executeBackgroundDelegate;
static loadAssemblyFunction loadAssemblyDelegate; static reloadFunction reloadDelegate;
SWITCH_MOD_DECLARE_NONSTD(void) InitManagedDelegates(runFunction run, executeFunction execute, executeBackgroundFunction executeBackground, loadAssemblyFunction loadAssembly) SWITCH_MOD_DECLARE_NONSTD(void) InitManagedDelegates(runFunction run, executeFunction execute, executeBackgroundFunction executeBackground, reloadFunction reload)
{ {
runDelegate = run; runDelegate = run;
executeDelegate = execute; executeDelegate = execute;
executeBackgroundDelegate = executeBackground; executeBackgroundDelegate = executeBackground;
loadAssemblyDelegate = loadAssembly; reloadDelegate = reload;
} }
// Sets up delegates (and anything else needed) on the ManagedSession object // Sets up delegates (and anything else needed) on the ManagedSession object
...@@ -362,7 +362,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_managed_load) ...@@ -362,7 +362,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_managed_load)
SWITCH_ADD_API(api_interface, "managedrun", "Run a module (ExecuteBackground)", managedrun_api_function, "<module> [<args>]"); SWITCH_ADD_API(api_interface, "managedrun", "Run a module (ExecuteBackground)", managedrun_api_function, "<module> [<args>]");
SWITCH_ADD_API(api_interface, "managed", "Run a module as an API function (Execute)", managed_api_function, "<module> [<args>]"); SWITCH_ADD_API(api_interface, "managed", "Run a module as an API function (Execute)", managed_api_function, "<module> [<args>]");
SWITCH_ADD_APP(app_interface, "managed", "Run CLI App", "Run an App on a channel", managed_app_function, "<modulename> [<args>]", SAF_NONE); SWITCH_ADD_APP(app_interface, "managed", "Run CLI App", "Run an App on a channel", managed_app_function, "<modulename> [<args>]", SAF_NONE);
SWITCH_ADD_API(api_interface, "managedload", "Load assembly", managed_loadassembly, "<filename>"); SWITCH_ADD_API(api_interface, "managedreload", "Force [re]load of a file", managedreload_api_function, "<filename>");
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
...@@ -406,16 +406,14 @@ SWITCH_STANDARD_APP(managed_app_function) ...@@ -406,16 +406,14 @@ SWITCH_STANDARD_APP(managed_app_function)
} }
} }
SWITCH_STANDARD_API(managed_loadassembly) SWITCH_STANDARD_API(managedreload_api_function)
{ {
if (switch_strlen_zero(cmd)) { if (switch_strlen_zero(cmd)) {
stream->write_function(stream, "-ERR no args specified!\n"); stream->write_function(stream, "-ERR no args specified!\n");
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
if (loadAssemblyDelegate(cmd)) { if (!(reloadDelegate(cmd))) {
stream->write_function(stream, "+OK\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Execute failed for %s (unknown module or exception).\n", cmd);
} else {
stream->write_function(stream, "-ERR LoadAssembly returned false (invalid file or exception).\n");
} }
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
......
\dev\swig\swig.exe -I..\..\..\include -v -O -c++ -csharp -namespace FreeSWITCH.Native -dllimport mod_managed freeswitch.i \dev\swig\swig.exe -I..\..\..\include -v -O -c++ -csharp -namespace FreeSWITCH.Native -dllimport mod_managed -DSWIG_CSHARP_NO_STRING_HELPER freeswitch.i
del swig.csx del swig.csx
@ECHO OFF @ECHO OFF
for %%X in (*.cs) do type %%X >> swig.csx for %%X in (*.cs) do type %%X >> swig.csx
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论