I want to test mono for embedding it into my C++ application. I was following the articles http://www.mono-project.com/Scripting_With_Mono, http://www.mono-project.com/Embedding_Mono and the examples here http://anonsvn.mono-project.com/viewvc/trunk/mono/samples/embed/.
So far everything worked well, although I don't understand the restriction for mono_jit_init to be callable just once.
So I'm able to load assemblies into the domain and run them, as well as expose some c methods to the Jit. It is possible to load different assemblies, but obviously each assembly can be loaded only once. If the assembly changes on disk after the first load calling mono_domain_assembly_open again, does not reload the changed assembly.
Is there any way to achieve the reloading?
-Frank
_______________________________________________
Mono-devel-list mailing list
Mono-de...@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list
thank you very much!
Implementing your answer mad me stumble over this one https://bugzilla.novell.com/show_bug.cgi?id=624498.
Did you find a workaround? Win7 is one of my deployment platforms.
On a related note is there a way to invoke the mcs compiler from within the code to compile some .cs file.
Of course one could try to invoke mcs with a system call or ExecuteProcess but is there something more convenient?
As far as I read about the evaluator it seems not to so well suited for this purpose since i don't want/ need line-by-line action or repl.
-Frank
Am 24.07.2010 um 13:53 schrieb Lucas Meijer:
> Hey Frank,
>> I want to test mono for embedding it into my C++ application. I was following the articles http://www.mono-project.com/Scripting_With_Mono, http://www.mono-project.com/Embedding_Mono and the examples here http://anonsvn.mono-project.com/viewvc/trunk/mono/samples/embed/.
>> So far everything worked well, although I don't understand the restriction for mono_jit_init to be callable just once.
>> So I'm able to load assemblies into the domain and run them, as well as expose some c methods to the Jit. It is possible to load different assemblies, but obviously each assembly can be loaded only once. If the assembly changes on disk after the first load calling mono_domain_assembly_open again, does not reload the changed assembly.
>> Is there any way to achieve the reloading?
> You can only call mono_jit_init() once. However you can achieve what you want by creating a new domain (mono_domain_create()), and loading your assemblies in that domain. when you decide you want to reload an assembly, you would need to unload your domain, and create a new one again in which you can load your updated assembly. (on win32, you need to make sure you load your assembly into memory first, and ask mono to load it from memory, otherwise it will keep a lock on the on disk assembly, preventing another process from overwriting it).
>
> This does mean that you basically loose all your instantiated objects and program state. Depending on what problem you're trying to solve, you can try to somehow store your program's state, then unload domain, recreate domain, and then somehow restore your program's state. that's what we do in unity.
>
> Be aware that there's quite significant memory leaks currently when unloading a domain. It's mostly leaking wrapper functions in marshall.c. Depending how on much code you've jitted it might or might not become enough to be a problem.
>
> Bye, Lucas
Look at System.CodeDom.Compiler.CodeDomProvider. Something like that:
CodeDomProvider provider = CodeDomProvider.CreateProvider ("C#");
CompilerParameters parms = new CompilerParameters ();
params.GenerateExecutable = true;
params.OutputAssembly = "test.exe";
provider.CompileAssemblyFromFile (parms, new string [] {"test.cs"});
Then wrap this code in a handy C# method that can be
conveniently mono_runtime_invoke()-ed from C++.
Robert
I want to test mono for embedding it into my C++ application. So far everything worked out rather well, but I'd like to have more of a script-like behavior. To be precise I'd like to provide the users of my application with the ability to write a rather complete .cs file (or even many of them) which interface with the methods of the host application. At the moment I need to invoke mcs manually in order to get this functionality (the assemblies are then executed with an embedded Jit ). However from browsing the web and the gmcs.exe assembly it seems possible to write a small c# program (which loads the gmcs.exe assembly) and invokes the compiler from source. Can the InvokeCompiler method in gmcs be called from outside? maybe even from c++?
Thank you in advance!
Frank
answering myself her. I almost works. I get a compiled assembly as the result of the following calls from c++:
MonoDomain* child = mono_domain_create_appdomain("MooseQT Compiler Domain",NULL);
mono_domain_set(child,0);
MonoAssembly* assembly = mono_domain_assembly_open(mono_domain_get(), "/Users/fuchs/Work/Codes/Libraries/mono_160737/lib/mono/2.0/gmcs.exe");
if (!assembly)
exit (2);
MonoClass *klass;
MonoMethod *method = NULL, *m = NULL;
klass = mono_class_from_name(mono_assembly_get_image(assembly), "Mono.CSharp", "Driver");
gpointer iter=NULL;
while ((m = mono_class_get_methods (klass, &iter)))
{
if (strcmp (mono_method_get_name (m), "Main") == 0)
method = m;
}
gpointer args[1];
args [0] = mono_array_new(mono_domain_get(),mono_get_string_class(), 1);
MonoString* string_mono=mono_string_new(mono_domain_get(), "/Users/fuchs/Documents/Eclipse/MooseQT/ScriptTests/Mono/mono.2.6.4/test_hello.cs");
mono_array_set((MonoArray*)args[0], gpointer, 0, string_mono);
mono_runtime_invoke(method, NULL, args, NULL);
mono_domain_set(mpDomain,10000);
mono_domain_unload(child);
However, the hosting app stops/ crashes due to the Environment.Exit() calls in Moose.CSharp.Driver.Main.
Can this be circumvented somehow? Can I ignore these Exit statements somehow ... why do they act beyond the JIT?
-Frank
> On 24.07.2010 15:11, Frank Fuchs wrote:
>>
>> On a related note is there a way to invoke the mcs compiler from within the code to compile some .cs file.
>> Of course one could try to invoke mcs with a system call or ExecuteProcess but is there something more convenient?
>> As far as I read about the evaluator it seems not to so well suited for this purpose since i don't want/ need line-by-line action or repl.
>
>
> Look at System.CodeDom.Compiler.CodeDomProvider. Something like that:
>
> CodeDomProvider provider = CodeDomProvider.CreateProvider ("C#");
> CompilerParameters parms = new CompilerParameters ();
> params.GenerateExecutable = true;
> params.OutputAssembly = "test.exe";
> provider.CompileAssemblyFromFile (parms, new string [] {"test.cs"});
>
> Then wrap this code in a handy C# method that can be
> conveniently mono_runtime_invoke()-ed from C++.
>
> Robert