C# AI Interface, and Proof of concept C# AI
Moderators: hoijui, Moderators
- hughperkins
- AI Developer
- Posts: 836
- Joined: 17 Oct 2006, 04:14
- hughperkins
- AI Developer
- Posts: 836
- Joined: 17 Oct 2006, 04:14
Added notes on Mono binding creation to Wiki at:
http://taspring.clan-sy.com/wiki/GlobalAI_Mono_Bindings
Could make a good project for anyone who is interested in Mono, C++ inter-language bindings or writing a GlobalAI in Mono.
http://taspring.clan-sy.com/wiki/GlobalAI_Mono_Bindings
Could make a good project for anyone who is interested in Mono, C++ inter-language bindings or writing a GlobalAI in Mono.
- hughperkins
- AI Developer
- Posts: 836
- Joined: 17 Oct 2006, 04:14
There's a pretty complete bunch of prototypes within the downloads on the page, partly from me partly from jelmer. What's missing is bringing the prototypes together to create the generator.I don't know nearly enough to start
The place to start is the MonoEmbeddedTest from jelmer. See jelmer's post earlier in this thread. This demonstrates:
*calling a static function in C# from C++
*calling a static C++ function from C#
*returning a pointer to a static function in C# to C++
*calling the pointed-to C# function from C++
Theres nothing stopping you doing it especially since it would make CSAI corssplatform.
I on the other hand have my own projects to be busy with, and I'm not going to commit to a C# project untill I can be sure it's crossplatform.
Besides I cant compile any of the mono stuff and I havent a clue how I'd test any of it, its all something I dont wanna touch or think about right now
I on the other hand have my own projects to be busy with, and I'm not going to commit to a C# project untill I can be sure it's crossplatform.
Besides I cant compile any of the mono stuff and I havent a clue how I'd test any of it, its all something I dont wanna touch or think about right now
- hughperkins
- AI Developer
- Posts: 836
- Joined: 17 Oct 2006, 04:14
- hughperkins
- AI Developer
- Posts: 836
- Joined: 17 Oct 2006, 04:14
Ok, hours of pain later... it's like this:
Code: Select all
domain = mono_jit_init ("AILauncher");
if (!domain)
throw std::runtime_error ("Couldn't create mono JIT runtime.");
mono_debug_init(MONO_DEBUG_FORMAT_MONO);
mono_debug_init_1( domain );
// load the managed dll
assembly = mono_domain_assembly_open (domain, dll);
if (!assembly)
throw std::runtime_error("failed to load " + std::string(dll));
mono_debug_init_2( assembly );
image = mono_assembly_get_image(assembly);
- hughperkins
- AI Developer
- Posts: 836
- Joined: 17 Oct 2006, 04:14
There's a nearly complete Mono bindings at AI/Global/CSAI/MonoLoader
This includes a wrapper layer to provide CSAI compatibility. If you thought that unwrapped ABIC looks ugly, take a look at unwrapped Mono layer:
With wrapper layer this becomes:
What's missing is essentially anything involving arrays.
This includes a wrapper layer to provide CSAI compatibility. If you thought that unwrapped ABIC looks ugly, take a look at unwrapped Mono layer:
Code: Select all
ABICInterface.IAICallback_SendTextMsg( aicallback, "Unit created: " + ABICInterface.UnitDef_get_name( unitdef ), 0 );
Code: Select all
aicallback.SendTextMsg( "Unit created: " + unitdef.name, 0 );
- hughperkins
- AI Developer
- Posts: 836
- Joined: 17 Oct 2006, 04:14
- hughperkins
- AI Developer
- Posts: 836
- Joined: 17 Oct 2006, 04:14
- hughperkins
- AI Developer
- Posts: 836
- Joined: 17 Oct 2006, 04:14
CSAI-compatible MonoLoader committed to SVN (r2670).
AI/Global/CSAI/MonoLoader
Note: maximum one MonoLoader AI per game.
Just for info, a lot of pain went into building this loader, Mono Embedding is non-trivial and undocumented.
Edit: how to build this:
On Windows:
First build GlobalAIInterfaces, which powers the generators:
Either, use Visual C# Express 2005:
*Open rts/ExternalAI/GlobalAIInterfaces with Visual C# Express 2005
*Build
Or, use batch file:
*change into rts/ExternalAI/GlobalAIInterfaces
*edit generate.bat with paths to mono or .Net and to Spring source and application
*run generate.bat
Next build MonoLoader:
*change into AI/Global/CSAI/MonoLoader
*edit build.bat with the path of spring, spring source, mono and mingw
*run build.bat
For an example AI, you can use CSAI2, which is in progress but does run. To build CSAI2, either:
*Either: open AI/Global/CSAI/CSAI2/CSAI2 with Visual C# 2005 Express and build
*Or: use nant. Just change into AI/Global/CSAI/CSAI2/CSAI2 and run "nant", with nant in the path
Edit: to run this, you'll need to copy some mono dlls into the spring directory. The files to copy are:
from mono/bin into TASpring directory:
iconv.dll
libglib-2.0-0.dll
mono.dll
intl.dll
libgmodule-2.0-0.dll
libgthread-2.0-0.dll
lib/mono/1.0 into TASpring/lib/mono/1.0:
mscorlib.dll
mscorlib.dll.mdb
lib/mono/2.0 into TASpring/lib/mono/2.0:
mscorlib.dll
mscorlib.dll.mdb
everything in lib/mono/gac/System into TASpring/lib/mono/gac/System
everything in lib/mono/gac/System.Xml into TASpring/lib/mono/gac/System.Xml
(if you dont have the last ones you get wierd unexplained crashes.)
edit: Dev notes for MonoLoader maintainers
*delegates can be passed from C# to C as IntPtrs
*make sure to store the IntPtr as an object instance before giving it to C, so it doesnt get gc'd
*make sure to put a gc lock on the C# object, from within C, to prevent it being gc'd
*strings are passed as MonoStrings, except when calling from C into Mono via a delegate function
*function pointers use the default platform calling convention, which is __stdcall on Windows and __cdecl on Linux
It doesnt seem possible to load multiple assemblies with the same class inside in Mono. It crashes the runtime. THis means that .reloadai implemented as for .Net wont work.
We could use AppDomains for this, but its lagtastic. Just modify the comments on lines 457 and 458 of CSAICInterface.cs to convince yourself of this. (you'll need to uncomment the compilation and deployment of MonoLoaderProxy.dll in the build.bat file for this to work).
Probably the only possible solution is to unload the Mono runtime and reload the entire runtime and assemblies. Untested.
Note that it's not currently possible to run multiple CSAIs within MonoLoader without using separate AppDomains. This is because CSAI uses Singleton pattern throughout, which means that in Mono, there's only one instance shared between all AIs.
Edit: just for info, note that each of these dev points, including the one-liners, was learnt following several hours of crashes and testing
AI/Global/CSAI/MonoLoader
Note: maximum one MonoLoader AI per game.
Just for info, a lot of pain went into building this loader, Mono Embedding is non-trivial and undocumented.
Edit: how to build this:
On Windows:
First build GlobalAIInterfaces, which powers the generators:
Either, use Visual C# Express 2005:
*Open rts/ExternalAI/GlobalAIInterfaces with Visual C# Express 2005
*Build
Or, use batch file:
*change into rts/ExternalAI/GlobalAIInterfaces
*edit generate.bat with paths to mono or .Net and to Spring source and application
*run generate.bat
Next build MonoLoader:
*change into AI/Global/CSAI/MonoLoader
*edit build.bat with the path of spring, spring source, mono and mingw
*run build.bat
For an example AI, you can use CSAI2, which is in progress but does run. To build CSAI2, either:
*Either: open AI/Global/CSAI/CSAI2/CSAI2 with Visual C# 2005 Express and build
*Or: use nant. Just change into AI/Global/CSAI/CSAI2/CSAI2 and run "nant", with nant in the path
Edit: to run this, you'll need to copy some mono dlls into the spring directory. The files to copy are:
from mono/bin into TASpring directory:
iconv.dll
libglib-2.0-0.dll
mono.dll
intl.dll
libgmodule-2.0-0.dll
libgthread-2.0-0.dll
lib/mono/1.0 into TASpring/lib/mono/1.0:
mscorlib.dll
mscorlib.dll.mdb
lib/mono/2.0 into TASpring/lib/mono/2.0:
mscorlib.dll
mscorlib.dll.mdb
everything in lib/mono/gac/System into TASpring/lib/mono/gac/System
everything in lib/mono/gac/System.Xml into TASpring/lib/mono/gac/System.Xml
(if you dont have the last ones you get wierd unexplained crashes.)
edit: Dev notes for MonoLoader maintainers
*delegates can be passed from C# to C as IntPtrs
*make sure to store the IntPtr as an object instance before giving it to C, so it doesnt get gc'd
*make sure to put a gc lock on the C# object, from within C, to prevent it being gc'd
*strings are passed as MonoStrings, except when calling from C into Mono via a delegate function
*function pointers use the default platform calling convention, which is __stdcall on Windows and __cdecl on Linux
It doesnt seem possible to load multiple assemblies with the same class inside in Mono. It crashes the runtime. THis means that .reloadai implemented as for .Net wont work.
We could use AppDomains for this, but its lagtastic. Just modify the comments on lines 457 and 458 of CSAICInterface.cs to convince yourself of this. (you'll need to uncomment the compilation and deployment of MonoLoaderProxy.dll in the build.bat file for this to work).
Probably the only possible solution is to unload the Mono runtime and reload the entire runtime and assemblies. Untested.
Note that it's not currently possible to run multiple CSAIs within MonoLoader without using separate AppDomains. This is because CSAI uses Singleton pattern throughout, which means that in Mono, there's only one instance shared between all AIs.
Edit: just for info, note that each of these dev points, including the one-liners, was learnt following several hours of crashes and testing

@Hugh: would it be possible to also create wrapper interface headers for IGlobalAI.h, IAICheats.h, IAIGroup.h, Weapon.h and WeaponDefHandler.h (from Sim/Weapons), and StdAfx.h (from System/)? I'm porting a C++ AI to use ABIC++ but it depends on those six files (update: actually only on IGlobalAI.h, IAICheats.h, WeaponDefHandler.h and StdAfx.h) and since they're neither covered by ABIC on the Spring side nor by ABIC++ on the AI side, I can't proceed :)
- hughperkins
- AI Developer
- Posts: 836
- Joined: 17 Oct 2006, 04:14
That's a lot of classes. If you could somehow make it so only asking for a single one at a time will help you, it would make it less intimidatingKloot wrote:@Hugh: would it be possible to also create wrapper interface headers for IGlobalAI.h, IAICheats.h, IAIGroup.h, Weapon.h and WeaponDefHandler.h (from Sim/Weapons), and StdAfx.h (from System/)? I'm porting a C++ AI to use ABIC++ but it depends on those six files (update: actually only on IGlobalAI.h, IAICheats.h, WeaponDefHandler.h and StdAfx.h) and since they're neither covered by ABIC on the Spring side nor by ABIC++ on the AI side, I can't proceed :)

If you want, I can teach you how the interfaces work, and you could take over their maintenance?