MouseTrap
22-02-2009, 02:25
This was a neat experiment, something to hold me over till O2H gets released (soon!!!???)
This allows you to load a .net EXE or DLL and call its internal methods. [using Mono]
It should also allow you have .net call back into the script, but im not sure how this would work without function pointers.
Here is the sample script. Excuse the fact that i've used fixed paths.. :roll:
uses "console"
DECLARE function mono_config_parse LIB "C:\Dev\Mono-2.2\bin\mono.dll" ALIAS "mono_config_parse" (file as asciiz)
DECLARE function mono_jit_init LIB "C:\Dev\Mono-2.2\bin\mono.dll" ALIAS "mono_jit_init" (file as asciiz) as long
DECLARE function mono_set_dirs LIB "C:\Dev\Mono-2.2\bin\mono.dll" ALIAS "mono_set_dirs" (asmdir as asciiz, cfgdir as asciiz) 'as long
DECLARE function mono_domain_assembly_open LIB "C:\Dev\Mono-2.2\bin\mono.dll" ALIAS "mono_domain_assembly_open" (byval domain as long, file as asciiz) as long
DECLARE function mono_assembly_get_image LIB "C:\Dev\Mono-2.2\bin\mono.dll" ALIAS "mono_assembly_get_image" (byval assembly as long) as long
DECLARE function mono_class_from_name LIB "C:\Dev\Mono-2.2\bin\mono.dll" ALIAS "mono_class_from_name" (byval image as long, namespace as asciiz, name as asciiz) as long
DECLARE function mono_object_new LIB "C:\Dev\Mono-2.2\bin\mono.dll" ALIAS "mono_object_new" (byval domain as long, byval _class as long) as long
DECLARE function mono_runtime_object_init LIB "C:\Dev\Mono-2.2\bin\mono.dll" ALIAS "mono_runtime_object_init" (byval obj as long) as long
Global MonoDomain as long
Global MonoAssembly as long
Global _Image as long
Global _Class as long '//'class' is a keyword, but not in the docs?!?
Global Obj as long
Global AsmFile as asciiz = "C:\Dev\Mono-2.2\bin\TestEmbed.exe" '// can be an 'exe' or 'dll' file
mono_config_parse($nul)
mono_set_dirs("C:\Dev\Mono-2.2\lib", "C:\Dev\Mono-2.2\etc")
'// Load the program and JIT //
MonoDomain= mono_jit_init (AsmFile)
printl MonoDomain
'// Open the assembly and get the handle
MonoAssembly = mono_domain_assembly_open(MonoDomain,Asmfile)
Printl MonoAssembly
'// get the asm instance
_image = mono_assembly_get_image(MonoAssembly)
printl _image
'// Get the class
_class = mono_class_from_name(_image, "Embed", "MyType")
Printl _class
'// create the object in memory
obj = mono_object_new(monodomain, _class)
printl obj
'// Instantiate the object, calling its default constructor
mono_runtime_object_init(obj)
printl "Done!"
sleep 2000
The code for c# 'TestEmbed' is:
using System;
namespace Embed {
class MyType {
int val = 5;
string str = "hello";
MyType () {
Console.WriteLine ("In ctor val is: {0}", val);
Console.WriteLine ("In ctor str is: {0}", str);
}
MyType (int v, byte[] array) {
Console.WriteLine ("In ctor (int, byte[]) got value: {0}, array len: {1}", v, array.Length);
}
void method () {
Console.WriteLine ("In method val is {0}", val);
Console.WriteLine ("In method str is: {0}", str);
}
int Value {
get {
return val;
}
}
string Message {
get {
return str;
}
}
void Values (ref int v, ref string s) {
Console.WriteLine ("In Values () v is {0}", v);
Console.WriteLine ("In Values () s is: {0}", s);
v = val;
s = str;
}
static void Fail () {
throw new Exception ();
}
static void Main () {
/* we do nothing here... */
Console.WriteLine ("This is inside mono...");
}
}
}
And when you run the script it returns:
28462848
28740912
3035256
3036552
34693104
In ctor val is: 5
In ctor str is: hello
Notice the last 2 lines are from the constructor of C# class.
This allows you to load a .net EXE or DLL and call its internal methods. [using Mono]
It should also allow you have .net call back into the script, but im not sure how this would work without function pointers.
Here is the sample script. Excuse the fact that i've used fixed paths.. :roll:
uses "console"
DECLARE function mono_config_parse LIB "C:\Dev\Mono-2.2\bin\mono.dll" ALIAS "mono_config_parse" (file as asciiz)
DECLARE function mono_jit_init LIB "C:\Dev\Mono-2.2\bin\mono.dll" ALIAS "mono_jit_init" (file as asciiz) as long
DECLARE function mono_set_dirs LIB "C:\Dev\Mono-2.2\bin\mono.dll" ALIAS "mono_set_dirs" (asmdir as asciiz, cfgdir as asciiz) 'as long
DECLARE function mono_domain_assembly_open LIB "C:\Dev\Mono-2.2\bin\mono.dll" ALIAS "mono_domain_assembly_open" (byval domain as long, file as asciiz) as long
DECLARE function mono_assembly_get_image LIB "C:\Dev\Mono-2.2\bin\mono.dll" ALIAS "mono_assembly_get_image" (byval assembly as long) as long
DECLARE function mono_class_from_name LIB "C:\Dev\Mono-2.2\bin\mono.dll" ALIAS "mono_class_from_name" (byval image as long, namespace as asciiz, name as asciiz) as long
DECLARE function mono_object_new LIB "C:\Dev\Mono-2.2\bin\mono.dll" ALIAS "mono_object_new" (byval domain as long, byval _class as long) as long
DECLARE function mono_runtime_object_init LIB "C:\Dev\Mono-2.2\bin\mono.dll" ALIAS "mono_runtime_object_init" (byval obj as long) as long
Global MonoDomain as long
Global MonoAssembly as long
Global _Image as long
Global _Class as long '//'class' is a keyword, but not in the docs?!?
Global Obj as long
Global AsmFile as asciiz = "C:\Dev\Mono-2.2\bin\TestEmbed.exe" '// can be an 'exe' or 'dll' file
mono_config_parse($nul)
mono_set_dirs("C:\Dev\Mono-2.2\lib", "C:\Dev\Mono-2.2\etc")
'// Load the program and JIT //
MonoDomain= mono_jit_init (AsmFile)
printl MonoDomain
'// Open the assembly and get the handle
MonoAssembly = mono_domain_assembly_open(MonoDomain,Asmfile)
Printl MonoAssembly
'// get the asm instance
_image = mono_assembly_get_image(MonoAssembly)
printl _image
'// Get the class
_class = mono_class_from_name(_image, "Embed", "MyType")
Printl _class
'// create the object in memory
obj = mono_object_new(monodomain, _class)
printl obj
'// Instantiate the object, calling its default constructor
mono_runtime_object_init(obj)
printl "Done!"
sleep 2000
The code for c# 'TestEmbed' is:
using System;
namespace Embed {
class MyType {
int val = 5;
string str = "hello";
MyType () {
Console.WriteLine ("In ctor val is: {0}", val);
Console.WriteLine ("In ctor str is: {0}", str);
}
MyType (int v, byte[] array) {
Console.WriteLine ("In ctor (int, byte[]) got value: {0}, array len: {1}", v, array.Length);
}
void method () {
Console.WriteLine ("In method val is {0}", val);
Console.WriteLine ("In method str is: {0}", str);
}
int Value {
get {
return val;
}
}
string Message {
get {
return str;
}
}
void Values (ref int v, ref string s) {
Console.WriteLine ("In Values () v is {0}", v);
Console.WriteLine ("In Values () s is: {0}", s);
v = val;
s = str;
}
static void Fail () {
throw new Exception ();
}
static void Main () {
/* we do nothing here... */
Console.WriteLine ("This is inside mono...");
}
}
}
And when you run the script it returns:
28462848
28740912
3035256
3036552
34693104
In ctor val is: 5
In ctor str is: hello
Notice the last 2 lines are from the constructor of C# class.